<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>C++2.0新特性 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/30.805597a8.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/15.fbdfc4ee.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/2.570d8a23.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/24.6f596516.js"><link rel="prefetch" href="/assets/js/25.14067b60.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/5.6f47322c.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>C++2.0新特性</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#📑-目录" class="sidebar-link">📑 目录</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⭐️-big-five⭐️" class="sidebar-link">⭐️.Big five⭐️</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⭐️核心中英文对照" class="sidebar-link">⭐️核心中英文对照</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#✅-『语法部分』" class="sidebar-link">✅ 『语法部分』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_01-演进、环境与资源" class="sidebar-link">01.演进、环境与资源</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-1-你应具备的基础" class="sidebar-link">1.1.你应具备的基础</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-2-我们的目标" class="sidebar-link">1.2.我们的目标</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-3-支持c-11的开关" class="sidebar-link">1.3.支持C++11的开关</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-4-网络资源" class="sidebar-link">1.4.网络资源</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-5-书籍推荐" class="sidebar-link">1.5.书籍推荐</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-6-测试是否进入c-11" class="sidebar-link">1.6.测试是否进入C++11</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_1-7-重磅出击" class="sidebar-link">1.7.重磅出击</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_02-variadic-template『可变模板参数』✅⭐️" class="sidebar-link">02.Variadic Template『可变模板参数』✅⭐️</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_03-『3个东西』" class="sidebar-link">03.『3个东西』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#『-补充自后一个视频』" class="sidebar-link">『 补充自后一个视频』</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_04-uniform-initialization，一致性的初始化" class="sidebar-link">04. Uniform Initialization，一致性的初始化</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#为什么支持『uniform-initialization』？" class="sidebar-link">为什么支持『uniform initialization』？</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_05-初始化列表-上" class="sidebar-link">05.初始化列表(上)</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_06-初始化列表-下" class="sidebar-link">06.初始化列表(下)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_6-1-关于如果没有initializer-list它的存在" class="sidebar-link">6.1.关于如果没有initializer_list它的存在</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_6-2-影响深远" class="sidebar-link">6.2.影响深远</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_6-3-示范一下算法的如何使用" class="sidebar-link">6.3.示范一下算法的如何使用</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_07-explicit-for-ctors-taking-『more-than』-one-argument" class="sidebar-link">07. Explicit for ctors taking 『more than』 one argument</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#『c-2-0开始的』c-2-0新特性『c-98有很小的用途』" class="sidebar-link">『C++2.0开始的』C++2.0新特性『C++98有很小的用途』</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_08-基于范围的for语句" class="sidebar-link">08.基于范围的for语句</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_09-default-delete⭐️" class="sidebar-link">09. =default, =delete⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_9-1-我们叫『big-five』" class="sidebar-link">9.1.我们叫『Big five』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_9-2-delete和-default" class="sidebar-link">9.2.=delete和=default</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_9-3-一般函数？" class="sidebar-link">9.3.一般函数？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_9-4-3个class" class="sidebar-link">9.4.3个class</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_9-5-boost中的手法" class="sidebar-link">9.5.boost中的手法</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_10-alias-template" class="sidebar-link">10.Alias Template</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_10-1-脑洞大开开始" class="sidebar-link">10.1.脑洞大开开始</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_11-template-template-parameter" class="sidebar-link">11.Template template parameter</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_11-0-『可以说是前面的续集』" class="sidebar-link">11.0.『可以说是前面的续集』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_12-type-alias-noexcept-override-final" class="sidebar-link">12. Type Alias, noexcept, override, final</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_12-1-type-alias，类型的化名" class="sidebar-link">12.1.Type Alias，类型的化名</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_12-2-noexcept" class="sidebar-link">12.2.noexcept</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_12-3-override" class="sidebar-link">12.3.override</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_12-4-final" class="sidebar-link">12.4.final</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳13-decltype『关键字』" class="sidebar-link">⏳13. decltype『关键字』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_3分钟开始" class="sidebar-link">3分钟开始</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳14-lambdas" class="sidebar-link">⏳14. lambdas</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#✅-可变模板参数系列" class="sidebar-link">✅ 可变模板参数系列</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_15-variadic-templates-1" class="sidebar-link">15.Variadic Templates 1</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_15-1-开始7大" class="sidebar-link">15.1.开始7大</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_15-2-例1" class="sidebar-link">15.2.例1</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_16-variadic-templates-2" class="sidebar-link">16. Variadic Templates 2</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳17-variadic-templates-3" class="sidebar-link">⏳17. Variadic Templates 3</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳18-variadic-templates-4" class="sidebar-link">⏳18. Variadic Templates 4</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳19-variadic-templates-5" class="sidebar-link">⏳19. Variadic Templates 5</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳20-variadic-templates-6-1" class="sidebar-link">⏳20. Variadic Templates 6(1)</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳21-variadic-templates-7-c-keywords" class="sidebar-link">⏳21. Variadic Templates_7 &amp; C++ Keywords</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_21-c-关键字" class="sidebar-link">21.C++关键字</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#✅-『标准库部分』" class="sidebar-link">✅ 『标准库部分』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_22-标准库-源代码分布" class="sidebar-link">22.标准库-源代码分布</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_23-右值引用和move语义『移动语义-move-semantic』⭐️" class="sidebar-link">23.右值引用和move语义『移动语义/move semantic』⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_23-1-big-five⭐️" class="sidebar-link">23.1.Big five⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_23-2-面试" class="sidebar-link">23.2.面试</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#⏳24-perfect-forwarding，完美转发" class="sidebar-link">⏳24.Perfect Forwarding，完美转发</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_25-写一个move-aware-class" class="sidebar-link">25.写一个Move-aware class</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_25-1-编码的坑⭐️" class="sidebar-link">25.1.编码的坑⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_25-2-move的和析构函数判别null" class="sidebar-link">25.2.move的和析构函数判别NULL</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_25-3-为什么重载-和-呢？⭐️" class="sidebar-link">25.3.为什么重载&lt;和=呢？⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_25-4-后续测试的准备" class="sidebar-link">25.4.后续测试的准备</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-move-aware-class-对容器的『效能测试』" class="sidebar-link">26.Move-aware class 对容器的『效能测试』</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-1-vector的测试" class="sidebar-link">26.1.vector的测试</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-2-测试list" class="sidebar-link">26.2.测试list</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-3-测试deque" class="sidebar-link">26.3.测试deque</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-4-测试multiset" class="sidebar-link">26.4.测试multiset</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-5-测试unordered-multiset" class="sidebar-link">26.5.测试unordered_multiset</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-6-测试结果⭐️" class="sidebar-link">26.6.测试结果⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#_26-7-讨论⭐️" class="sidebar-link">26.7.讨论⭐️</a></li></ul></li><li><a href="/01.Language/Cpp/PPT03.C%2B%2B2.0%E6%96%B0%E7%89%B9%E6%80%A7.html#参考资料" class="sidebar-link">参考资料</a><ul class="sidebar-sub-headers"></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="c-2-0新特性"><a href="#c-2-0新特性" class="header-anchor">#</a> C++2.0新特性</h1> <ul><li>『本课程涵盖了C++11和C++14』</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>&lt;font style=&quot;background:yellow&quot;&gt;
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h2 id="📑-目录"><a href="#📑-目录" class="header-anchor">#</a> 📑 目录</h2> <p>[TOC]</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>一、语法部分
01.演进、环境与资源
02.Variadic Template『可变模板参数』
✅03.『3个东西』
『1』Spaces in Template Expression
『2』nullptr and std::nullptr_t
『3』Automatic Type Deduction with auto，通过auto自动类型扣除

✅04.Unifrom Initialization『一致性的初始化』
✅05.Initializer_list（上）
06. Initializer_list（下）
07. Explicit for ctors taking 『more than』 one argument
✅08.基于范围的for语句
09.=default, =delete
10.Alias Template
11.Template template parameter
12.『4个东西』
&gt; - Type Alias，类型的化名
&gt; - noexcept
&gt; - override
&gt; - final
13.decltype『关键字』
14.lambdas

✅23.右值引用和move语义（游戏公司面试考了）
	- 缺乏右值引用和引用（又叫“左值引用”）
	- 新引进的名称：临终值，在C++11中为右值引用专门定义了临终值（eXpiring value）这一概念
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br></div></div><h2 id="⭐️-big-five⭐️"><a href="#⭐️-big-five⭐️" class="header-anchor">#</a> ⭐️.<code>Big five</code>⭐️</h2> <ul><li>牛客<a href="https://www.nowcoder.com/test/question/done?tid=44174655&qid=305235#summary" target="_blank" rel="noopener noreferrer">例题<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li>C++编译器好智能化</li> <li>但我决定可能不仅仅是这些，可能还要更多的，比如C++11引入</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>如果你只是声明一个空类，不做任何事情的话
    编译器会自动为你生成：
    <span class="token number">1</span>、一个默认的构造函数『构造函数』（ctor）
    <span class="token number">2</span>、一个默认的拷贝构造函数『拷贝构造函数』（copy constructor）
    <span class="token number">3</span>、一个默认的拷贝赋值操作符『拷贝赋值操作符函数』（copy assignment <span class="token keyword">operator</span> <span class="token operator">=</span> ）
    <span class="token number">4</span>、一个默认的析构函数。『析构函数』（dtor）
这些函数只有在第一次被调用时，才会别编译器创建。
    『『所有这些函数都是<span class="token keyword">inline</span>和<span class="token keyword">public</span>的。』』
    
此外，在C<span class="token operator">++</span><span class="token number">11</span>
    这样特殊的函数，从上面<span class="token number">4</span>个成了<span class="token number">6</span>个，增加的为
    move 的copy constructor
    move 的copy assignment <span class="token keyword">operator</span> <span class="token operator">=</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br></div></div><h2 id="⭐️核心中英文对照"><a href="#⭐️核心中英文对照" class="header-anchor">#</a> ⭐️核心中英文对照</h2> <ul><li><code>Variadic Template</code>『可变模板参数』</li> <li>3个东西
<ul><li>『1』Spaces in Template Expression，在模板表达式中的“空格”</li> <li>『2』<code>nullptr</code> and <code>std::nullptr_t</code></li> <li>『3』Automatic Type Deduction with auto，通过auto自动类型扣除</li></ul></li> <li>从</li></ul> <h2 id="✅-『语法部分』"><a href="#✅-『语法部分』" class="header-anchor">#</a> ✅ 『语法部分』</h2> <ul><li>01.演进、环境与资源</li> <li>02.可变模板参数</li> <li>03.模板表达式中的空格、<code>nullptr</code> and std--<code>nullptr_t</code>、<code>Automatic Type Deduction with auto</code></li> <li>04.Unifrom Initialization，一致性的初始化</li></ul> <h2 id="_01-演进、环境与资源"><a href="#_01-演进、环境与资源" class="header-anchor">#</a> 01.演进、环境与资源</h2> <ul><li><font style="background:yellow;">在软件界，还没有成熟的就是0.几</font>，所以1.0版本是个正式成熟的作品</li> <li>1.1-1.2这样的一些小改版</li> <li>C++2.0又是一个里程碑</li></ul> <p>『本课程涵盖了C++11和C++14』</p> <blockquote><p>这个课程，新特性被我分为2部分，1个是语言部分，1个是标准库部分。</p></blockquote> <h3 id="_1-1-你应具备的基础"><a href="#_1-1-你应具备的基础" class="header-anchor">#</a> 1.1.你应具备的基础</h3> <ul><li>C++语法,语意</li></ul> <h3 id="_1-2-我们的目标"><a href="#_1-2-我们的目标" class="header-anchor">#</a> 1.2.我们的目标</h3> <ul><li><p>较全面地认识C++2.0新特性，并从实例获得经验</p></li> <li><p>『较全面』的，并且从实例中获得体验。</p></li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712082522367.png" alt="image-20210712082522367"></p> <ul><li>C++14是对C++11的一些小地方的修缮。『最重要是1.0和2.0的』</li> <li>『本课程涵盖C++11和14』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712082747249.png" alt="image-20210712082747249"></p> <ul><li>我们还是希望，大家能很快改掉你的旧的写法，用新的写法</li> <li>我们列出的都是『2.0』新增加的一些头文件。</li></ul> <blockquote><p><strong>注意</strong>：**标准库的东西都是放在『命名空间std』**中，所以在你使用这些东西的时候，你要把它全名写出来。因此，一个东西的全名，你要带着那个命名空间。</p> <p>当然，怕麻烦用using namespace std;</p></blockquote> <ul><li>TR1那个版本的C++</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>TR1的那些东西是被放在，命名空间std的次要的命名空间tr1
所以当时，你必须<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token operator">::</span>tr1 
早期是这样的，但是现在已经搬到std里面来了！！！
『也就是说<span class="token number">2.0</span>里面，我们就不需要管那个TR1了』
TR1的技术和组件还全部存在，但是现在被放到std里面了
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221156014.png" alt="image-20210712221156014"></p> <ul><li>学习语言上的东西，当然要去测试。了解编译器对2.0的支持度</li></ul> <p>网页推荐：</p> <ul><li><a href="https://isocpp.org/" target="_blank" rel="noopener noreferrer">https://isocpp.org/<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>『这个里面说明了“编译器”支持C++11和14如何』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221245996.png" alt="image-20210712221245996"></p> <ul><li>继续</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221414388.png" alt="image-20210712221414388"></p> <ul><li>这样可以查看，手上的编译器对这些的支持程度。</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221456271.png" alt="image-20210712221456271"></p> <ul><li>自己做测试用的编译器是：DevC++5.11这个编译器。</li> <li>这个上面的<code>gcc</code>一向号称对C++支持度最好</li></ul> <h3 id="_1-3-支持c-11的开关"><a href="#_1-3-支持c-11的开关" class="header-anchor">#</a> 1.3.支持C++11的开关</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726085945236.png" alt="image-20210726085945236"></p> <h3 id="_1-4-网络资源"><a href="#_1-4-网络资源" class="header-anchor">#</a> 1.4.网络资源</h3> <ul><li>这个是C++之父自己的网页『有关于C++11的部分』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090122593.png" alt="image-20210726090122593"></p> <ul><li>其他网页『我3个常用的，查的』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090232490.png" alt="image-20210726090232490"></p> <ul><li>还有</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090309150.png" alt="image-20210726090309150"></p> <ul><li>还有gnu C自己的官方网站</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090340167.png" alt="image-20210726090340167"></p> <ul><li>上面的都很好，没有什么谁更好</li></ul> <h3 id="_1-5-书籍推荐"><a href="#_1-5-书籍推荐" class="header-anchor">#</a> 1.5.书籍推荐</h3> <ul><li>effective Modern C++是专家建议『这本书只讲新东西！』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090511638.png" alt="image-20210726090511638"></p> <ul><li>下面是看源代码的工具</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726090835834.png" alt="image-20210726090835834"></p> <ul><li>书籍</li> <li>你将获得的代码：<code>Test-C++2.0.cpp</code>『当然可能将来不叫这个名字』</li> <li>其内含蓄本踝程野C++2.0 New Features的测试</li></ul> <h3 id="_1-6-测试是否进入c-11"><a href="#_1-6-测试是否进入c-11" class="header-anchor">#</a> 1.6.测试是否进入C++11</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726091606287.png" alt="image-20210726091606287"></p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>

	cout<span class="token operator">&lt;&lt;</span>__cplusplus<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token function">system</span><span class="token punctuation">(</span><span class="token string">&quot;pause&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br></div></div><h3 id="_1-7-重磅出击"><a href="#_1-7-重磅出击" class="header-anchor">#</a> 1.7.重磅出击</h3> <ul><li>可能学到的东西如下：</li></ul> <p><strong>（1）语言</strong></p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>语言<span class="token operator">:</span>
<span class="token operator">-</span> Variadic Templates  <span class="token comment">//叫作：</span>
<span class="token operator">-</span> move Semantics	『标记』
<span class="token operator">-</span> <span class="token keyword">auto</span>				『标记』
<span class="token operator">-</span> Range<span class="token operator">-</span>base <span class="token keyword">for</span> loop 『标记』
<span class="token operator">-</span> Initializer list
<span class="token operator">-</span> Lambdas
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><p><strong>（2）标准库</strong></p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token operator">-</span> type_traits	『标记』
<span class="token operator">-</span> Unordered容器
<span class="token operator">-</span> forward_list	『标记』
<span class="token operator">-</span> array			『标记』
<span class="token operator">-</span> tuple			『标记』
<span class="token operator">-</span> Con<span class="token operator">-</span>currency
<span class="token operator">-</span> RegEx
<span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="_02-variadic-template『可变模板参数』✅⭐️"><a href="#_02-variadic-template『可变模板参数』✅⭐️" class="header-anchor">#</a> 02.Variadic Template『可变模板参数』✅⭐️</h2> <p>嗯嗯如果把C++2.0提供新的东西当成是一些武器，而武器分类的话有手枪、步枪、自动步枪、机关枪、大炮哈哈，还有些什么东西呢？我也不是武器专家啊，但如果这样子分类的话，我要谈的第一个东西给各位一个震撼:那就是<strong>原子弹级的</strong>了。
这个震撼弹叫做Variadic Templates模板，所以这跟模板有关。</p> <p>事实上C加加我们说语言的部分、标准库的部分，标准库的部分呢大量用到模板，所以模板是非常重要的。
模板这一边的程度的进化，使得标准库呢使得C++好像一只老虎长了翅膀一样，然后呃他的变化呢令人目瞪口呆。
这个所以模板很重要啊，这个如果你对模板不是非常熟悉的话呢，赶快停下来，把模板复习一下。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711140020852.png" alt="image-20210711140020852"></p> <blockquote><p>Variadic Templates，可变模板</p></blockquote> <ul><li>Variadic Templates这个叫作：其实没有单词Variadic，这个叫作『</li> <li>因为其实没有这个字，但是这个字的字头Varia，变化。
所以大家可以想象跟变化有点关系。当然也许在你听这个课程的时候，或者再过几年你再去查这个字，说不定就有了这个就好像在C++2.0二点零呢。
有一个东西叫tuple，在几年前我在查，查不到这个字，我不知道怎么念，他该念top还是念top，我也不太确定，不过现在再去查。有。哈哈。你念top也可以，但是美国口音你念top也可以呢。是英国口音啊，我查到的是这样。</li> <li>看下面的代码，黄色部分竟然有个『<code>...</code>』，我平常在写在做这个投影片的时候，有时候我因为东西很多，比如说要让大家看一个class的设计，因为代码太多了，我只捡取最重要的部分，其他就点点点来表示，把它暂时忽略不计。这给我们带来了困扰，因为没想到<font style="background:yellow;">到了C++2.0这个『<code>...</code>』成为了关键字的一部分！！</font></li> <li>实际上，这个『<code>...</code>』在以前C的时代就存在了，在那个printf中</li> <li>大家从c开始学习，可能第一个接触到的function就是print，让你把东西打印出来，你可以加上任意的参数实参。所以我们联想到，『<code>...</code>』是可以接受任意变化个数的东西。</li></ul> <p>这个点点点的原来以前就有了，那么以前的做法是怎么样呢？这边我就不去提以前的事情了，这printf这边我就不去提了。
回到这里来，现在这个点点点在C++2.0，被用来做什么呢也是用来表现<strong>一组东西</strong>，我们叫Pack，一包东西。
好，我现在把这一块放大，再抄一次啊，下一页来，就是这一块。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711140552267.png" alt="image-20210711140552267"></p> <ul><li><p>那这个个数随意，可是每一个的个数那呃<strong>这个参数的个数随意</strong>，</p></li> <li><p>而且它还有一个更大特性是<strong>每一个参数的type类型也随意</strong>！这就太神奇了。</p></li></ul> <p>所以这个行的意思是它的类型啊这个是传引用，它是把reference传引用。这这件事情跟现在要谈的无关。
有没有这个符号是都可以，无所谓。</p> <p>好，这意思就是说他可以是任意类型，所以这个Types这个字，这是在这个例子里面我自己命的名称啊叫Types，蓝色这个他就应该我们就应该告诉编译器说它到底是什么类型呢？
我们要在模板参数这边写出来。呃这个。可是又要告诉模板说这个啊所以这个Types就代表我们就是菜谱啊，很多个菜吧。
这些type是什么呢？也不必写，因为我刚刚说可以接受任意的太本，所以他这边有点点点他的name后面加点点点。
这里是这里所出现点点点出现的是两个地方。我再整理一次啊。</p> <p>这一个函数我的设计是要他允许他能够接受任意个数的参数，而且每一个参数的tap也是任意的。我就写这样子，两个。至于为什么这个点点点点是加在这一个我自己取的符号的后头，而这个点点点却是加在不是加在这个后头，是加在这个time这个关键字的后头啊为什么这个加在这里这个加在这里？
那这是语法的定义了，我们就是你你多写几次你就熟悉了，就是要这么写。
写成这样之后，这个就叫where，ID，types。</p> <p>所以用中文来讲，我可以说它就是一种数量不定的模板，参数数量不参数数量不定的模板都可以看你啊怎么去运用你的中文。所以我可以传进任意个数的参数，而且参数也呃type也是任意，这就是这两行的意思。</p> <ul><li><p><strong>有了这样的东西之后，到底可以帮助我们做什么事呢</strong>？</p></li> <li><p>这边就有一个例子了，可以帮助我们做rpc<strong>递归</strong></p></li></ul> <p>因为这个版本现在你看到的这一个。
他所收到的是其实它是两个模板参数，这是第一个。
呃是所以如果我传五个进去给他，我prime我放五个参数。
其实在这里是被分成一汉其余那这个其余就是四嘛。</p> <p>然后呢剩下的那一包就是四十二，再传进去，所以第一个就是四十二，剩下那一包呢那就是零了啊</p> <ul><li><strong>这个点点点也包括零个</strong>。</li></ul> <p>好，那把四十二再印出来，那剩下这一包现在也都是零个，他再传进去就分解不出一加零了，它本身也就是零。
零是零加零。零，不是。这一加零啊，所以这个零在这里就不能够调用到这一个。
所以<strong>为了要处理边界条件，处理这个最后的状态了，还得再写另外一个函数</strong>。
这个。所以当最后一次剩下两个没有参数的时候，会调用到上面这个一这个版本，而<strong>如果没有一这个版本，那就编译错误</strong>。
所以当我们在使用template，呃very idea的东西的时候，一定会需要写一个处理最后情况的。</p> <p>这个东西在这里是函数嘛，所以就写一个函数出来，<strong>下一页就是对类来讲</strong>，那要写一个一个类，但是他是做什么事，等一下你会看到。就分别针对，<strong>这一页是针对函数</strong>。</p> <p>这非常好，帮助我们做request递归，这个递归的过程是为了把不定个数的参数把它一一分解。</p> <ul><li><p>这弹性太大了！</p> <ul><li>任意个数的参数</li> <li>任意参数类型</li></ul></li> <li><p>后边，我们会去讲标准库中怎样去实现一些东西，我们去挖出来。『那时候可能恍然大悟，果然是原子弹』</p></li> <li><p>解决问题：</p> <ul><li>2和3同时存在的时候，是否可以并存？？？</li> <li>答案：好像不能并存？歧义？在我们过去的基础上，我们认为是这样。</li> <li><font style="background:yellow;">不过，其实是可以并存的，在Variadic Template这个主题上！！</font></li> <li>那么并存的话，它到底调用到谁呢？刚刚不是说分不出？</li> <li>这2个同时存在，谁泛化？谁比较特化？</li> <li>现在不宣布答案。。『呃呃呃』</li></ul></li> <li><p>下面是我们用到Variadic Template它的，把参数逐一分开的特性！</p></li> <li><p>这一页的更加有实用价值</p></li> <li><p>因为，后头我们在讲标准库的时候，讲<code>unordered函数</code>的时候，需要这个技巧：单纯的，</p></li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711140641501.png" alt="image-20210711140641501"></p> <ul><li><p>自己调用自己才是递归</p></li> <li><p>如果调用的是别人的function，不能叫递归</p></li> <li><p>下一页又有个例子</p></li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711140820762.png" alt="image-20210711140820762"></p> <ul><li>这样可以做出tuple</li> <li>tuple是可以任意给个数，给任意个类型。。。</li> <li>『我觉得，可能是为了tuple设计的？？』</li></ul> <h2 id="_03-『3个东西』"><a href="#_03-『3个东西』" class="header-anchor">#</a> 03.『3个东西』</h2> <ul><li>『1』Spaces in Template Expression，在模板表达式中的“空格”</li> <li>『2』<code>nullptr</code> and <code>std::nullptr_t</code></li> <li>『3』Automatic Type Deduction with auto，通过auto自动类型扣除</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221904552.png" alt="image-20210712221904552"></p> <p>在temperate expression 模板表达式里面的那个空格，这空格一向很讨厌。如果你过去有经验了，你一定很清楚我在说什么。
就是这样子。像这个呢写一个模板，如果这个模板参数本身又是一个模板的话，这个右边就会出现两个大挂号啊。尖刮号。这个<strong>在过去呢一定要把它空开来</strong>。
这个病意思就是说编译器如果你这个连在一起，编译器编在这里会以为那是一个操作符。然后他前后边前后看就看不懂。这个编译器在当时不够聪明。
那现在进化终于他懂了，所以这个观这个空格可以拿掉了再拿掉了。
<strong>从C++11这边就o k</strong> 。这个就是这么小的一个东西啊，我们现在很轻松的一个主题。好，我去看看，他告诉你可以这么写，那我就很有兴趣。那标准库是不是都改成这样的呢？的确呃，当时啊我在看4.5版。
四点五版。
这边就已经变成这样子了。所以他已经开始运用新的这一种语法。</p> <ul><li>C++11的编译器变聪明了2333，可以那么写，标准库都变了</li></ul> <blockquote><p>nullptr and std::nullptr_t</p></blockquote> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221938797.png" alt="image-20210712221938797"></p> <p>然后nullptr以及那这到底是什么呢？看起来对它对比，而是对比我这边准备的是一个type。标准库底下的一个Type，所以左边这个大概是个object咯，一个对象咯？一个东西喽？ 不<strong>过也有人把他当作，说他是一个关键字</strong>！！这个倒也无所谓了。
好，这个东西叫null point。就是<strong>零的,空的,指针空的指针</strong>。</p> <ul><li>这边说C++11 的允许你使用nullpoint 这个东西，这个关键字来取代替0，或者是代替NULL</li></ul> <p>额，NULL是怎么用的呢？
在在此之前，2011之前。
你要把一根指针设为空指针的话，设为零指针的话呢，你赋值给他是0也可以，可是感觉不太对味！！</p> <p>那个味道不太对！！
<strong>指针嘛，怎么让他变成零呢</strong>？？？
所以『通常』就设为大写的这个NULL， 其实呢这个NULL定义就是0『23333』</p> <p><strong>那现在说啊，我们把它区开来吧，因为零是个数值，NULL应该是个指针，那不然我们</strong>。是不是把它区分开来呢？<strong>就出现了新的关键字</strong>。</p> <p>现在看这个例子，我是记得两个函数叫f 都叫f， 所以说函数重载咯，他们的参数不一样！！</p> <p>如果我这么调用，<strong>上面2个是函数的声明啊，下面3个是调用</strong>。如果是这么调用的话。
编译器一看，0是个整数。他不把0当成一个指针呢，所以调用的是后面有注解。第二个是上面这个版本。如果是下面这样呢。传的是NULL指针
就算not permanent，这个关键词是灵好了，但是<strong>编译器也知道，其实你的意思是来他是要传一个指针进去</strong>。</p> <p>所以第2种呢是这个版本。后面游戏。那如果你传这个。<strong>大写的NULL进去会怎么样呢？<strong>那就看看这个NULL 是什么了。刚刚我说</strong>在前头2011之前，这个NULL 其实定有一个它define 他定义就是0</strong>。</p> <ul><li>如果这样的话，第二个就是上面那个版本，因为零这个整数要到上面的版本，这里有写了。如果呢大写的NULL那是零，这样的是上面那个版本。</li></ul> <p>但如果这个NULL不是零，但那其实是0啊。但是我是说<strong>如果</strong>你传了一个你定义的一个符号进去，他不是0的话！！</p> <p>那编译器就不知道，比如说你曾经一个3,2,7,6,8。
32768是个整数吗？当然是！！
可以说是一个地址呢？？也是啊，也可能是啊？
所以编译器就不知道你到底是要调用谁</p> <p><strong>好。那这一个东西（指着nullptr）！！</strong> <strong>这个东西它的类型是什么</strong>？</p> <p>是这一种呃，下面这段文字是这种Type『指着<code>std::nullptr_t</code>
那这个Type 定义在这一个头文件里头。这个Type又是什么呢？我实在很想看一看他到底是什么??所以我就把这头文件挖出来。</p> <p>前面不是有提过啊，这个是一个<code>延伸文件名称</code>在·。h·的。</p> <p><strong>不过新的标准是前面加一个c</strong> 所以这两个其实那是同一种同一个东西。</p> <p>同一种东西lef 可能是这一个内涵他吧。我得实际去看才下。</p> <p>好，那这里面就有我们刚刚在讨论这一个type 到底是什么Type，这边就有个定义了。好，这个是又是一个很小的东西，叫做nullptr</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712222010434.png" alt="image-20210712222010434"></p> <p>》 关键字auto</p> <p>以前在谈auto 这个字眼的时候会出现在什么地方？</p> <p>我们会说啊一个function有一个auto  variable（ auto 变量）</p> <p><strong>当时在讲这个字的时候，是说为什么讲一个变量是auto 变量呢？</strong></p> <p>我们说1个函数，如果他有local， local 就是本地的变量的话！
<strong>那这个函数结束的时候，这个变量的生命就消失了，他自动会消失掉</strong>。</p> <p><strong>所以我们把local 局部本地的这一种，一个函数里头的这种变量叫做local 变量，又叫做auto变量。是因为这样，他自己</strong>的生命会<strong>自动</strong>消失。</p> <blockquote><p>可是现在谈的不是这个！！</p></blockquote> <p>现在谈的这个auto 呢。是这么用的
这么用：他的意思是告诉编译器说。
我<strong>啊，现在也不知道这个变量是什么类型，你就自己帮我推一把</strong>！！</p> <p>那我就告诉你说，这是一个auto 变量。『此auto非彼auto』</p> <p>『『其实编译器在编译的过程里面<strong>当然知道</strong>什么东西是什么类型。』』
也<strong>因此才可以做模板的实参推</strong>导argument deduction 实参推导。</p> <p>编译器本来就具备这个能力，现在在C++2.0**，它就把这个能力表现出来**，让你去使用，就是这里的aoto。</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>现今有很多经典的语言：
这一种经典的，古典的这种语言呢！！
从Pascal开始到C++到java到C#都很重视type ，变量的type 类型。

所以如果是使用这种语言的呢，都特别的对于类型敏感！！！呃，特别的概念清楚。
所以我们是希望程序员要很清楚类型的体系。不要。
因为有了这个屠龙宝刀。
反正他会帮我推，我就什么东西。auto，不要这样！
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><ul><li>所以这个auto这个关键字。主要是帮助我们怎么样呢？</li></ul> <p>这边有讲了：使用auto 是特别有用，在什么地方呢？</p> <p>在于这个Type 啊。很长，你实在懒得打那么多字。或者这个type 实在是很复杂。
所以一时间想不出来你，你大约隐约有印象，但是你一时间可能写代码来容易有点出错！！！
这两者我们都可以举例子。
1、太长的这一种。像以前在写迭代器i就最常碰到这种情况。</p> <p>但是我们其实心里面得知道</p> <p>2、那第二种呢就是说这个类型呢有点复杂，了一下想不出来。
lamda表达式！！</p> <p><strong>lamda表达式，它其实是一个没有名称的函数！！『或者叫仿函数！！！</strong>
没有名称的仿函数</p> <p>好，暂时不管他，总之我们很少人能够写出一个Lamda表达式的类型出来，但现在你是要这个那么大，用l 就表示这个Lamda。嗯，本来必须写出l 的类型。
现在说啊，实在是也写不出来了啊，就是auto。</p> <h3 id="『-补充自后一个视频』"><a href="#『-补充自后一个视频』" class="header-anchor">#</a> 『 补充自后一个视频』</h3> <ul><li>关于auto另外2张投影片。</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712222028848.png" alt="image-20210712222028848"></p> <ul><li>的</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712222045256.png" alt="image-20210712222045256"></p> <p>我总是很好奇，所以有这些新的语法出来，或者一些新的更好的一个东西东西就对象啊出来。那自己本身标准库自己本身有没有去用到他呢？比如说。
点你说我现在有auto，看起来是关键字很不错啊。标准库有没有去用啊？
我就找了一下，这很容易找到你用刚刚我讲的任何的一个全文检索版本，很容易找到。</p> <p>但如果是旧版本的这个操作符的返回类型，那就长啊就是圈起来这一块。
我们现在不去解释他。我有另外一门课叫新加压标准库比同学会谈到，像这种东西怎么会成为这么长呢？是成为一个迭代器。<strong>里头的经过萃取机萃 取出它的difference type</strong>。difference type 就是那个距离<strong>两个迭代器的距离</strong>。
为什么会说需要设计这个那个其他的课程会去提我们这里不具体。所以这两个的差别啊这么长一串就变成auto这个字眼。标准库本身也有在使用这一个新的关键字。</p> <h2 id="_04-uniform-initialization，一致性的初始化"><a href="#_04-uniform-initialization，一致性的初始化" class="header-anchor">#</a> 04. <code>Uniform Initialization</code>，一致性的初始化</h2> <ul><li><strong>Uniform Initialization</strong>，一致性的初始化</li> <li>4分钟的时候，才开始</li> <li>这个特性，背后其实是<strong>下一节</strong>的在支持</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712222124171.png" alt="image-20210712222124171"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//翻译
在CH+11之前，程序员，尤其是新手，很容易被如何初始化变量或对象的问题弄糊涂。
初始化可以使用括号、大括号和或赋值运算符进行。

出于这个原因，CH+11引入了统一初始化的概念，这意味着对于任何初始化，您都可以使用一种通用语法。该语法使用大括号，因此现在可以使用以下内容:

其实是利用一个事实：编译器看到{ t1, t2 ... tn }便做出一个initializer_list&lt;T&gt;，它关联至array&lt;T,n&gt;。
调用函数（例如ctor）时该array内的元素可被编译器分解逐一传给函数。
但若函数参数是个initializer_list&lt;T&gt;，调用者却不能给予数个T参数然后以为他们会被自动转为一个initializer_list&lt;T&gt;传入
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br></div></div><p>接下来我们谈：</p> <ul><li><p>uniform initialization 叫做『一致性的初始化』，设初值啦</p></li> <li><p>既然谈到一致性，<strong>大概表示过去不一致哦</strong>，</p></li> <li><p>Q：是这样吗？？</p></li> <li><p>A：是这样的！</p></li></ul> <p><strong>在C++11之前，程序员哈，特别是一些新手很容易困惑于1件事情</strong>：什么事情呢？</p> <ul><li>就是要初始化变量，或者初始化一个对象的时候该怎么写？
<ul><li>这个初始化呢，可能是发生在<strong>小括号</strong><code>()</code></li> <li>发生在<strong>大括号</strong></li> <li>或者是发生在<strong>赋值符号</strong>上面</li></ul></li></ul> <p>这一段话的意思：这个就这3个动作，可以表现这一段话的意思。这是我写的某一段代码里头，以前写的代码里头呢。但是不止在设定初值的时候。
这是一种写法。
下面这是一种写法。
这是第三种写法。『『指着下面的3个框框说』』』这是呼应上面这段文字。</p> <ul><li><p>现在C++2.0，说基于这个原因，现在导入了一个观念，叫做<code>uniform initialization</code>，<code>一致性的初始化</code>。他的意思是什么呢？</p></li> <li><p><strong>任何初始化动作，你都可以用一个共同语法，只有一种语法</strong>。</p></li> <li><p><font style="background:yellow;">那就是用大括号！</font>这个叫一致性。</p></li></ul> <p>当然现在你还是习惯用以前的那也不会错，这个都是回溯相容的啊。</p> <p>这个不可能推翻掉以前的东西。但现在。你可以全部都用大括号，<strong>比如上面这样黄色的部分都是。<strong>这是一个数组array，大括号，就是</strong>在变量的后面直接放大挂耗电量</strong>。名字叫这个吗？</p> <p>在变量的后面直接放<code>{ }</code>就是做一个初始化的动作，直接设初值。</p> <p>继续讨论！
<strong>虽然看起来形式都一样，其实技术上有点不同！</strong></p> <ul><li>1、首先，我告诉大家，这个大括号一出现，其实拿来当初值，是因为这一段：：<strong>利用一个事实</strong>，什么事实呢？编译器只要看到大括号一出现。他就做出一个这种东西出来『指的 <code>initializer_list</code>』 我们后再过2,3张投影片，就要开始讲这个东西。所以做，所以左手边，黄色的部分有4段，其实就是四个音量。这个内部其实是<strong>关联</strong>到一个array。这个array 指的是，标准库里面提供的一个容器。</li></ul> <h3 id="为什么支持『uniform-initialization』？"><a href="#为什么支持『uniform-initialization』？" class="header-anchor">#</a> 为什么支持『uniform initialization』？</h3> <ul><li><p>2、注意一下这边我的表现了。说做出一个这一种东西出来，他的类型是t 那t是什么？现在就呼应：：</p> <ul><li><font style="background:yellow;">为什么他在新的标准里面提供？『一致性的初始化**』其实是背后有所谓的<code>initialize list</code> 在做支持**。</font>我这里还没讲完，但是你看前看下一</li></ul></li> <li><p>3、但是这边还有一句话。但是如果调用了这个函数呢，它的参数就是这种东西。因should like the least。调用者却不能给予数个，然后以他们就是说这句话是什么意思？有的函数的设计，他接受的就是一个这种东西。</p> <ul><li>我们后面投影片，接下来就要讲这种东西嘛 。
在此之前，2.0之前你从来没看过，因为这个也是新东西。但<strong>现在说如果有的函数它的定义的时候</strong>就这种东西的话，那现在刚刚不是说过这些蓝黄色的部分，就是形成这种东西吗？所以就整个就传过去，<strong>就不会像这样逐一分解啊</strong>。</li> <li>所以在函数的调用这里就是不知道函数这里在调用这一些东西。大括号就形成了一个<code>initialize list</code></li></ul></li> <li><p>4、<strong>原因</strong>：『『『如果这个构造函数的设计不一，它本身不是函数，可以有很多个嘛，**其中有一个版本。他就是接受这种，<code>initialize list</code> **. 他就是接受这种的话，那黄色的这一些东西就整包转过去。』』</p></li> <li><p>编译器会自动的把它拆解一个一个的来丢过来，来调用这个函数。所以这是两种情况这是两种情况。啊，具体说说，但是如果他参数本身是这一样的一个。调用者却不能。<strong>这什么意思呢？</strong>
以刚刚构造函数来讲。如果他只有这样可接受这种东西。如果说要这个版本的话。
<strong>调用者必须准备一个这种东西去调用它！</strong></p></li> <li><p><strong>不能够呃，好像杂牌军一样</strong>，自己准备了几个呢，就以为这几个会被编一些合成一包来调用。</p></li> <li><p><strong>后面还会有更详细的解释。当我们去理解<code>initialize list</code>这里面的设计就会更清楚。</strong></p></li></ul> <p>一在整理一次是什么？这个地方已经形成了那个一包了。</p> <ul><li><font style="background:yellow;">**而构造函数也有一个版本，是接受这样一包。那那太好了。一包传给一包。我怎么能说出这一段话呢？因为我看过标准过的源代码。 **所有的容器都有这一种构造函数！</font></li></ul> <p>这一段源代码全文检索得到的结果呢，在后面投影片我也会展现给你看。</p> <p>『2』但是这这个情况又不一样了。这一个也是形成一包这个名字太长了，我就这一包好了哈。你说。like the least the er. 他也是形成一包。
这背后有一个array，这个这个说法完全跟上面一样。
在元素是两个。但是他在调用comm px 的构造函数的时候。
count 构造函数。</p> <p>『『没有一个版本是接受一把握这种东西。』』</p> <p>你有一包东西，你传给的那一个，你要调用那个函数，他不接受一包，他就说一个一个。所以这时候说什么？编译器会把那一包的那两个元素分解，传给构造函数。
这都是看了。因为我看了这个一次性的<strong>设定初值之方法</strong>啊，这当然很简单的，你看啊就是这么用，但是他背后牵扯的东西，就看了源代码挖出来以后整理成这一些文字就更深入的东西！</p> <p>如果这么复杂，你不想理解的话，那就是你回到这里来黄色的部分你就这么使用就对了。然后接下来我们就要去谈：这个<code>initializer_list</code></p> <h2 id="_05-初始化列表-上"><a href="#_05-初始化列表-上" class="header-anchor">#</a> 05.初始化列表(上)</h2> <ul><li><strong>Initializer_list</strong>，初始化列表</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713093543665.png" alt="image-20210713093543665"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//翻译
initializer_list强制进行所谓的值初始化，这意味着即使是基础数据类型的局部变量(通常具有未定义的初始值)也由零初始化(or nullptr，如果它是指针的话):
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li>刚刚谈的这一个一致化的设初值动作，可<strong>能会让你掉以轻心</strong>！！</li></ul> <p>觉得说：反正就是设初值嘛！那也不过我就把习惯性的把以前呢，呃好几种作用写法，我改成大括号的写法，或者我不改也没关系呀啊！</p> <p>呃，在使用设初值，在设初值这一件事情上面，的确它是个小事情。<font style="background:yellow;">但是为了完成刚刚讲的一致性的设初级的动作，<strong>它背后呢，所牵扯到一个新的设计，却对于标准库影响很大</strong>。</font></p> <p>刚刚有提到在设初值的这个大括号过程里面，其实你可以任意放元素。所以这又来一个任意放元素了，**这个有没有让你联想到一开始我们给你们重磅炸弹Variadic Template **。</p> <p><code>{ }</code>的背后其实是这个这一个东西做出来的。这并不是刚刚那颗原子弹的Variadic Template！不是啊不是，但是这1个呢也很重要，因为他也要来接受个数可变的元素！！</p> <p>东西有变化，这件事情本身就不太好实现出来。所以我们前面讲过Variadic Template可以实现这个这个<code>Initializer_list</code> 呢也是要来解决这个东西有变化的这个。那么现在要谈的就是说，那个大括号其实形成了形成了一个<code>Initializer_list</code></p> <p>我们先看一些小东西。这里说的事情是什么？
他可以设定初值，他本来就是在设定初值用的呀，不是吗？大括号一次化的射出刺动作吗？
但这里的意思是：像这种写法的话，i他到底是多少是不知道的，你不能假设他是0。</p> <ul><li><strong>我想这个从c 以来，可能老师都告诫过你，谆谆教会你很多次了。所以你如果需要一个初值，你要把它写出来，你不要默认的以为他有什么初值</strong>。</li></ul> <p>那下面这样呢，那这就是设初值，虽然你初值没有写，但是他就是你他为什么是0，因为现在的利现在的团队形式。<code>Initializer_list</code>的初值的对a 默认为是你。</p> <p>同样的道理，这一个这个值这是一个指针。它的初值是什么？不知道不知道他指向哪里。
但是如果是这样子写的话呢：</p> <ul><li><p>所以大括号可以用来设初值。</p></li> <li><p>1、然后我们看下面这一个。说如果你使用大瓜号。但是你里面放的东西和原来的类型，声明的所有的类型。这是**转不过去，那当然不要提了，编译器就停在这个地方。**报错。</p> <ul><li><font style="background:yellow;">但是如果<strong>转得过去的话，他是不允许你这个叫做缩小</strong>的。窄化的一个转换！比如说这5.0是应该这个浮点数。<strong>他转成整数，5.0应该转成5，本来就是共同的可以通过的。但是如果你用大括号就不能！</strong></font></li> <li>这边说error 这里有三个error，你看一下都是。都是一种窄化的转换。这这不不可以！</li></ul></li> <li><p>2、嗯，但是这一边呢<strong>是一些书籍上文章上写的是过于强硬，我实际在我的平台上面，我的平台是什么</strong>？前面讲过了，做了测试呢。<strong>他只是给警告！这是一个小小的地方呢来提醒大家。</strong>『可能只是警告！！！』 好，然后我们再往下来看一看，这个背后就是一个大瓜号所形成的其实是这么一种东西。
我们来好好的研究这个东西。</p></li> <li><p>他说他可以接受个数不定的元素进来，就是大括号里面你可以任意放元素！！</p></li></ul> <h2 id="_06-初始化列表-下"><a href="#_06-初始化列表-下" class="header-anchor">#</a> 06.初始化列表(下)</h2> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713093633037.png" alt="image-20210713093633037"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>翻译
为了支持（用户-定义类型）的初始化列表概念，C++11提供了类模板std::initializer_list&lt;&gt;

它可用于支持通过值列表或在任何其他你想处理一个值列表的地方。例如:
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><p>我们从一次性的初始化方式，设初值的方式谈到了那个大括号，其实是形成一个<code>initializer_list</code>
然后再谈到，那所谓<code>initializer_list</code>它只是一个观念，背后到底是什么呢？背后就是这一个class 的支撑。</p> <p>我前面提到说，也许你会掉以轻心，其实呢这个设初值嘛，形势反正就是大括号。那再往下挖在到底在挖什么呢？我说他背后要靠这个class 支撑，<strong>这个class 影响了标准库的实现</strong>。啊，在新的版本上啊有相当程度的影响，并且h后面也会介绍在下一张投影片哦，不对，就这一张投影片就会介绍。你也可能自己要需要用到这一个class。</p> <p>好，我们来看看。直接看例子吧。我写一个函数叫print。上面是定义，下面是调用的方式。如果我愿意。
我想要接受任意一个个数的东西。我觉得这么写，用这个<code>initializer_list</code>，这么写的话，使用者他就可以这样调用了。用大括号，形成了一串东西。我前面提过背后是一个array一个数组啊。</p> <ul><li>这一串东西<code>{12,3,啥的}</code>。编译器会把它变成是这，<strong>自动的</strong>把它写成是这一种东西<code>initializer_list</code>，然后存进来。所以他这是可以实现参数个数不定这个结果。</li></ul> <p>那前面的那个Variadic Template 重磅炸弹啊。<strong>Variadic Template他是比这个更厉害，他不但可以接受任意个数，而且这里面的类型都不，类型都不一样</strong>。那个我们前面已经介绍过观念的嘛。</p> <p>再一次让你区分两者的不同，这里面呢都必须是整数，为什么？因为这个print函数定义的时候说我要接受的是整数。传进来之后，我们看看怎么用。这也是一个你也可以把这个当成是一个容器，容器怎么用就很大家就很熟悉的。</p> <p>所以你也可能会需要写这种函数，那你就会要用到这一个。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713093725561.png" alt="image-20210713093725561"></p> <p>我们再看一个例子。我现在设置一个class 叫p。
这里有两个构造函数。</p> <ul><li><p>这个构造函数接受a b。</p></li> <li><p>这个构造函数呢接受的是一个这一种，这这一包哇，我从现在开始，我把这个叫一包，免得我这念出来实在太长了。这一包也就是我们标题的这个东西<code>initializer_list&lt;&gt;</code></p></li></ul> <p>我设计了两个版本。
我们看看，这是一个class。接下来呢我要做出四个对象，4个object。
有的是用<code>( )</code>，有的是用大括号在设值，我们看看谁会调用到谁，这里都有输出结果哦。</p> <p>好，我这边画了一个箭头。不要误会，我再说这个第二次调用调用到第一版本，我不是这个意思。
第二。p qrs 这q 啊。调用的也是第二版本，后面有后面是这个执行结果嘛。</p> <ul><li>啊，所以千万不要误会的这一条线的意思这一条线的意思是说当『复数』的时候是这种情况。
这等一下再说了。</li></ul> <p>好，我们来看看为什么是下面四个调到谁的解释一下。第一个动作。他小括号两个参数。
当然是先调用版本1啦，这完全吻合。</p> <p>第二呢。p, q r s, the q 呢浙大括号是形成一个一包。
一包就是这种东西啊。形成一包，所以当然是调用到二。</p> <p>第3三呢：qq rs 这个r 呢这个也是一包啊。所以调用呢也是版本二。</p> <p>第4呢：这个也是一包。这个等号这个你可能会想，这不是应该调用到操作符重载这个。算这个符号吗？</p> <p>啊，<strong>这个叫很多C++程序员，常常会即使你是老手的说。乍看之下也是会误会，其实这个因为它是在直接建立一个新的对象，所以调用的是构造函数！<strong>上面就是构造函数。
好，那他这也是一包啊，大括号是一包，所以这</strong>样道理是。版本2。</strong></p> <h3 id="_6-1-关于如果没有initializer-list它的存在"><a href="#_6-1-关于如果没有initializer-list它的存在" class="header-anchor">#</a> 6.1.关于如果没有<code>initializer_list</code>它的存在</h3> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>翻译
Without the constructor for the initializer list,the constructor taing two ints would be called to initialize q and s, while the initializationof r would be invalid.

如果没有初始化列表的构造函数，包含两个int的构造函数将被调用来初始化q和s，而r的初始化将是无效的。

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><p><strong>如果没有二，只有一的话。</strong>
没有二啊。
只有一。
那么下面这个p q r s 会怎么样？
不影响p 对不对？基本来就是调用意义嘛。
其物呢？
修正两个。</p> <p><strong>本来应该调用版本二，现在版本2不在。那么编译器，会把这一包东西。拆解。拆解为两个，这个例子拆解为例啊。下一个例子就拆解为三个。好，这拆解为两个之后来看看</strong>！</p> <p>哦，这款版本1就是接受两个！于是他会调用到拷贝。这是这里所说的，如果你没有版本二的话。
那么那个接受两个参数的两个整数的那样一个构造函数啊，也就是这里的版本一。
他还是可以用来设q ns 刚刚才讲的是qu 啊。
他被拆解开来放进去。
在此也可以a s 是什么，s 跟q 是一样的嘛，都是要用构造函数，同一件事情。但是不能够拿来这个r 就不成立了。
因为啊拆解开来是三个参数。现在只有版本一。这是不吻合的。</p> <p><strong>我们借由这个非常细琐的探讨。目的是完全清楚这个initialize the list，它作为函数参数的时候什么情况被调用。</strong></p> <p>什么这个这个取舍，这版本一跟二的取舍。</p> <p>好，现在我来解释这一条线。
我要说这条线我要说明什么呢？</p> <ul><li><p>说。complex『复数』 就是这种情况。</p></li> <li><p><font style="background:yellow;">complex本身没有版本2这一种构造函数他只有1</font>。但是前面我们在。这样我来翻到前面去啊。复数。</p></li></ul> <p>右手边就是影响ize list 的源代码。
我这个人对技术的挖掘就有这个习惯，就是挖到我满意为止。</p> <p>现在对于要来看看怎么用是很清楚了，这个东西怎么做。
<strong>好，他的data ，我总是先看他数据的部分</strong>。
<strong>他的data 在这里。看到一个array。那前面已经打给各位打过底了，他背后是一个array 的支持</strong>。
还有一个长度。
但是<strong>这个array 呢它不是真的，而为他只是一个迭代器哟</strong>。不过好像他背后是一个array，而这里呢是一个头部，有那些指向头，我们可以推想是这样，我们还没有看细节呢。
在他的源代码里面，这边有一句话很重要，一个注解。
<strong>他说编译器能够调用一个private的 constructor，按理说就没有任何人没有任何人。能够以这种形式来创建一个对象喽。因为他是私有的</strong> <strong>但是他说编译器可以。而且编译器会！</strong></p> <p><strong>那边现在什么时候来做这个事情呢？就是在当他看到大括号的时候</strong>！
他就要制造出一个这种东西。
要制造出这种东西，他就会调用这一个地方，这是private
<font style="background:yellow;"><strong>编译器有无上权限！我们不能调用它，可以调用</strong>。</font>
他调用它是做什么事情呢？他传建了一个迭代器，跟那个大小。
事实上，那在这个地方解释就没有继续解释下去了。事实上我可以告诉你。
编译器在调用它之前，已经先准备好一个array。
然后把这个array的头传进来啊，长度存进来。</p> <p>传进来做什么，被他登记起来。
array是2.0的新特性。</p> <p>array的这是TR1的版本。
为什么我要加拿提TR1 呢？怕把大家吓着了。这个是四点九的版本。但是四点九的太复杂了。
我也花了不少时间才把它理清楚。所以我们要谈观念，我们其实拿的TR1来谈就够了。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210718123457758.png" alt="image-20210718123457758"></p> <p>好，那我们来看看。
一个array。其实就是。<strong>换一种形式来表现C++本身的数组</strong>，这种东西换了个形式，数组就是一块内存。
现在转成这种形式来表达，就可以用到标准库所有的容器所会用到的那种接口。所谓提供的那种接口。
什么头，begin，头指向头的迭代器，end 的就是指向尾巴。尾端的那个迭代器等等等。所以他的身份就会跟其他的容器一样。和其他容器一样带来什么好处呢？<strong>它就可以被那些七八十个算法来处理</strong>！</p> <p><strong>因为算法啊只认迭代器，所以他必须提供迭代器。</strong>
但是我们就讲到这样。</p> <p>右上角的代码：</p> <p>这样这个地方给一定十嘛。到底。呃，如果是是10的话，那么其实得到就是。
如果他如果是0呢，得到的是1哦。
<strong>所以你可以指定说我的array n长度是0，而实际上内部他会变成1，因为没有零这种程度array。他实现的小细节</strong>。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210718124239806.png" alt="image-20210718124239806"></p> <p>这句话的意思。看看源代码。当编译器调用这一个构造函数，要建立这一包东西的时候，他只是传递头进来，传长度进来。呃，<strong>这跟这一个指针就指向那一个array了他并没有内涵着他</strong>。
就是这个话的。
所以后面又讲了，如果把这一包东西。initialize the list <strong>to copy</strong> 的话。所产生出来的另外的那个东西，你copy 就有另外一个新东西产生出来的这个东西只是refer to the same 相同的底部的这些元素。应该是里头只有这根指针。c 一包东西里头只有指针指向array。所以拷贝过去是一个浅拷贝。<strong>他当然发现设计上。要做深拷贝也可以，不过他只是一个浅拷贝。我看这边我也没有把他拷贝的动作列出来。大概是没有</strong>。呃，好。没有，那我可以告诉你，他其实里头只是把指针拷贝过去。
那这样的意思就是原来的这一包跟新的这一包，它里头的两根指针就指到同一个array，这件事情当然是危险的危险。</p> <p>啊，会不会到底你会不会去把一个这一个一包东西去做拷贝动作呢？呃，不知道说万一你真的有去做拷贝，<strong>你要注意这句话。这一段话。他会形成一个两个指针指向同一个array。</strong></p> <h3 id="_6-2-影响深远"><a href="#_6-2-影响深远" class="header-anchor">#</a> 6.2.影响深远</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210718124423975.png" alt="image-20210718124423975"></p> <p>好。前面我提过。这个一包initialize the list。相当大幅度的影响了标准库里面的实现。
怎么讲这个话呢？我用那个全文检索工具去查看。
因这个这一句这个这个initialize the least。<strong>我找到了这么多的结果</strong>。
这字很小。</p> <p>我找到了，结果显示。这是一个容器容器vector 、dequeue、string、<strong>这个是算法啊，连算法都用到了啊</strong>，这个呢都是容器、容器还有算法。都用到这个东西。</p> <p>他们在做什么事情？<strong>这些容器现在的设计是。接受在构造的时候，构造函数接受你指定任意个数的一个元素，当成他的初值！</strong></p> <p>我现在把vector这一部分放大，其他容器都差不多。都这样啊，现在放大。这里面由于我这个地方全文检索，看到这四个函数。都有用到这一包的东西。所以我就把<strong>这四个函数</strong>。这个都有行号</p> <p>这四个函数呢所接受的参数都是这一包东西，蓝色的。那么在二点零版之前，c 加加二点零啊，谢谢大家。二零一一之前<strong>没有这种一包没有这个东</strong>西，所以这边的写法就要把更多的精力，更多的代码才能够去接受。数量不定的参数。</p> <p><font style="background:yellow;">所以我们说这一个东西要不就是像这样在标准库大量用到了。要不就是在前面我有一个例子是print，你可能会需要写出一个print 函数，接受任意个数的元素啊，那是你自己可能会用上。</font></p> <h3 id="_6-3-示范一下算法的如何使用"><a href="#_6-3-示范一下算法的如何使用" class="header-anchor">#</a> 6.3.示范一下算法的如何使用</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210718125036197.png" alt="image-20210718125036197"></p> <ul><li>那字符串本身的比大小方式，他有他自己独特的一套，我们叫做字典形式的排列次序。字典怎么排，各位很清楚吧。</li></ul> <p>为什么你能够放任意多个元素呢？因为现在mini 马跟max mara 有了一个新版本，旧版本仍然存在啊。版本是只放只接受两个参数，<strong>现在这个新版本可以接受任意参数。这不是很棒吗？</strong></p> <p>你的函数呢尤其特别在min跟max这两个函数身上，它的名称身上让你特别感受到，你可以放很多个元素进去，这是一件很合理的事情。而不是只发两个元素进去。</p> <p>我对于这个<code>initialize list</code>这一个class。深入的挖掘到这个地方。</p> <h2 id="_07-explicit-for-ctors-taking-『more-than』-one-argument"><a href="#_07-explicit-for-ctors-taking-『more-than』-one-argument" class="header-anchor">#</a> 07. <code>Explicit for ctors taking 『more than』 one argument</code></h2> <ul><li>对于接受多个参数的运算符explicit</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713093815986.png" alt="image-20210713093815986"></p> <p>接下来这个主题explicit，小事情：这个标题说explicit，这个是一个关键词，
他要用来，用来干什么？<strong>是针对构造函数</strong>，并且<strong>是接受一个以上的实参</strong>！！
要用，要讨论这一件事情，那在化成代码就是这样的形式！！！
这是一个class。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713093857753.png" alt="image-20210713093857753"></p> <p>标题说要讨论这件事情：要讨论这些事情之前，<strong>要去看一看2.0之前</strong>的一个主题，看我把more than 划掉了！！！</p> <p>『『『所以我们先看看explicit的这个关键字，<strong>用在一个实参</strong>的构造函数身上，<strong>那又是什么情况</strong>，然后才能去讨论2.0——一个以上的实参』』』
好，我们先看这个——现在我这里有两个class，在我自己写的这个复数class，这跟标准库那个不一样！！大写的，标准库是小写的没有冲突。</p> <p>左边这一个呢，这是左右是完全警醒的，所以你特别容易让你比对。
<strong>左左跟右唯一的差别在于右边</strong>，这个是。</p> <ul><li>explicit这个关键字，他其实用途其实很少，<strong>主要就是用在构造函</strong>数身上。</li></ul> <p>好，我们先看左边的。
你设计一个复数，接受实物跟虚部，如果你需不默认为零的话啊，你可能设计出这样的版本。</p> <p>这是你这么写的话，好，如果使用者这么用，看看会有什么结果！！这意思是说我有一个负数，他是十二加五i。下面这一行是我有第二个负数，他的值是。上面那一个加上五。这个家务啊。编译器看到加5。
他会去找出来，他会想办法把舞看能不能够转换成复数。</p> <p>所以（编译器)他去看看，那这一期就看能不能能不能把<strong>五变成五加零i。</strong>
根据刚刚的分析——好，编译器也够聪明啊，他知道哦！哎，你这边有一个默认的版本。所以，5他就把他要用这一各构造函数。变成你家零i。 所以这一行就会通过。得到了结果就就两个复数相加。『『如果这是你所欢迎的，当然那很好。』如果你不欢迎这一种。在这个负数这件事情身上，当然我们觉得很自然，因为对数学上确实是这样啊，我们觉得很自然。<strong>但是如果他其他的例子里</strong>面，你<strong>不想让编译器这么自动。</strong>『『这一种叫做隐式的』』把5暗中转换为了复数。。</p> <p>如果你不想要编译器这么自动的话。你可以在这边加上一个explicit！！
那就是告诉编译器说不要自作聪明！！要在我『『明确』日如果调用它，这在我明确调用构造函数的时候，你才来调用它。
啊，<strong>不要帮我做：on the table,————桌面下的转换。</strong>
所以当写出expressive 的时候，下面这一行这个。就会失败。因为你<strong>阻止了编译器的那些自动的行为。</strong></p> <p>像这样的话，编译器的报错信息是什么呢？在我所使用的，我前面讲过，我用什么样的编译器啊，在我所使用的的编译器上面，他就会说。no match for appropriate. 七。他找不到能够相匹配成功的函数。</p> <p>『『『这就是加 或不加explicit 差别的这里。』』</p> <p><strong>关键字explicit的就是明白的，明确的！！</strong></p> <p>换句话说就是告诉编译器，我这个函数要<strong>被明确</strong>的调用，你不要自动帮我做转换。
<strong>这个是在C++2.0之前，早就存在的事实和用法！！</strong>『『『注意，注意，C++2.0前的，是这种对于1个参数的用法！！只存在于单一实参才可以哦『『一个以上就和这个无关！！』』！</p> <h3 id="『c-2-0开始的』c-2-0新特性『c-98有很小的用途』"><a href="#『c-2-0开始的』c-2-0新特性『c-98有很小的用途』" class="header-anchor">#</a> 『C++2.0开始的』C++2.0新特性『C++98有很小的用途』</h3> <blockquote><p>易错的定义！</p></blockquote> <p>『指着左边』只有这种。像这个叫做什么？这个叫单一实参哈！
这话要<strong>解释的更透彻</strong>一点就是：<strong>它是两个参数</strong>，，<strong>但是你只要指定一个实参</strong>就可以了，因为第二是第二参数是默认有默认<strong>值，所以这一种叫做one argument</strong>。one argument 就可以调用。而且没有加explicit。所以有一句很长的术语啊，仔细听：叫做none explicit one argument constructor！！只有这种constructor的这种构造函数『『<strong>才能</strong>』』够做<strong>隐式的转换。</strong></p> <ul><li>『现在2.0』』这边说，不只是一个实参的，3个2个啊，一个以上的我都也提供explicit，禁止你做转换！！『神奇』</li></ul> <p>用法，就这样子，放在构造函数前面：**在我印象之中，这个关键字『『只用』在构造函数前面。**呃，<strong>在模板那边。好像也有一一个地方会用到explicit</strong>，<strong>但是那个非常非常少人用，</strong>，这个已经够少人在使用了。</p> <p>好，所以现在刚刚把那个故事讲完，现在回到这个故事来呢，就不必再说了。各位知道哈整个整个搬离过来一样的概念：现在这边有一段测试：加上explicit 之后，现在这个情况，那么我创建出这些对象。右上角这是一个类啊。我要根据这个类创建这些对象，『『有的成功，有的不成功』</p> <p>自己看注解！！</p> <h2 id="_08-基于范围的for语句"><a href="#_08-基于范围的for语句" class="header-anchor">#</a> 08.基于范围的for语句</h2> <blockquote><p>Range－based for statement，基于范围的for语句</p></blockquote> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711104712307.png" alt="image-20210711104712307"></p> <p>很小、很简单、很实用，我非常喜欢的。</p> <ul><li>冒号的左手边是一个声明，右手边是一个容器，就一堆数据，你只要这样就可以了。</li></ul> <p>那么for loop 这种写法呢。这一期把它编译出来的动作就是等同于什么呢？<strong>把右边这个容器的元素一个一个的取出来，放到左边这个decoration 去</strong>，这是一个声明嘛，就这么一个变量。</p> <p>右手边是一对是一对数据，只要是容器就可以了。那是这一个才刚刚才看过呀，就是那一包。就是那个<code>Initializer_list</code>，就是那个背后有array的那个东西。</p> <p>上到这里这个元素了，这个变量了。
那这个变量声明这里是一个reference 引用。
所以这个赋值就会变得很快。</p> <p><strong>有什么容器是不能让你改变元素的内容呢？</strong>
啊，这下看你对容器理解多少，我有另外一门课是C++标准库呢，曾经很<strong>深刻</strong>的提过这个问题！！！
<strong>那什么容器是不可以允许你直接用迭代器直接改变元素呢</strong>？
<strong>关联式容器都不可以</strong>！！！
<code>set ，set hash map</code> 等等等。
我刚刚提到<code>hash，hash_set和hash_map</code>在C++2.0换了一个新名称，叫做<code>unordered_set</code>和<code>unorder_map</code>的不定式啊，这个我们放到第二讲。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712083150263.png" alt="image-20210712083150263"></p> <ul><li>这种for循环，可以等价于右边2种，下面一种是调用的全局函数，让我们多认识一点，在C++2.0中，有这么2个全局函数！！是可以接受容器的</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712083306508.png" alt="image-20210712083306508"></p> <p>我们看这一页。
还有什么要注意的吗？for loop看起来就很好用啊，也都讲完了，说下这一夜我们看看。</p> <ul><li>这边说<code>nox expressive type conversion</code>显示类型的转换！！</li></ul> <p>没有这种。嗯。其实，to get an explicit 关键字。有关了。
啊。我们先不要管这些文字好了，先看看这一段。</p> <p>这个是刚刚才熟悉过的东西。
<font style="background:yellow;">有一个很长的术语叫做。<code>no explicit one argument constructor</code>. 这个就是one argument。</font>
只要搬离实参，就可以调用它们。
这个他加了显示explicit
<strong>所以不可以做转换哦，不可以，暗中转换的话，编译器不要自作聪明啊，他的意思是这样。</strong>
下面呢？</p> <p>如果我选择使用这么用啊，这个新式的for</p> <p>左边却是c 这种东西。
<strong>所以要转过去的时候。</strong> <strong>就看能不能转的过去喽。</strong>
本来字符串跟c 之间有什么关系呢？那我们也不知道啊，因为这C只是这里的一个例子而已。</p> <p>如果我但如果我的这一个这个c 他在他在。
<strong>他在某种情况下，本来跟字符串是有关联的。</strong>
因此好像本来吃不上，可以暗中的这个暗度陈仓啊，那慢慢的它转成了c。
假设c 是这么设计。</p> <p><font style="background:yellow;"><strong>但现在我要禁止这个事情。绝对不允许你。暗度陈仓我就加上explicit</strong>。</font></p> <p>这个for loop本拿到的每一个元素在做赋值动作的时候啊，如果类型不一样就要做转换。那<strong>如果当初源头的地方就不准</strong>转换的话当然就会失败在。</p> <p>哦，在for这个地方会失败。这是。我认为非常好用的。</p> <h2 id="_09-default-delete⭐️"><a href="#_09-default-delete⭐️" class="header-anchor">#</a> 09. <code>=default</code>, <code>=delete</code>⭐️</h2> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710183324249.png" alt="image-20210710183324249"></p> <ul><li>注意：<code>=defalut</code>和<code>=delete</code>都是1个整体，他们的那个等号一定要记得！</li></ul> <blockquote><p>可能的联想：<code>=delete</code>并不是我们以前熟悉的那个<code>delete</code>啥的动作</p></blockquote> <ul><li>可能的联想：<code>=defalut</code>，default默认：可能会让你联想到，你心目中的默认可能有：
<ul><li>默认构造函数</li> <li>默认拷贝构造</li> <li>默认拷贝赋值。对，这个东西就和那个东西有关系</li></ul></li> <li>所谓默认构造函数（default ctor）就是<strong>不需要任何实参</strong>，就能把它调用起来的，不需要任何<code>argument</code>实参。</li> <li>如果你没写，编译器会给你1个，编译器给你这个做什么用？什么都没做，（编译器不可能知道你想做什么事情，所以它只是一个空的函数）那空函数做什么用？</li> <li>如果你只是单一的class，它也没有什么用，但是<font style="background:yellow;"><strong>如果你这个class是要继承其他的父类的话，这个class，这个class的构造函数必须要调用父类的构造函数</strong></font>，这个调用的动作要放在哪里呢？？就要放在这个构造函数里面，所以，<strong>这个时候默认构造函数就有价值了</strong>。『<font style="background:yellow;">它仍然是个空的函数，但是编译器会在你看不到，你根本就看不到它嘛，编译器就会在那放一些隐藏在背后的代码</font>』『我们在投影片另外有1页，有些文字会讲到这个事情』</li></ul> <blockquote><p>C++2.0现在提供</p></blockquote> <ul><li>如果你强制加上C++2.0提供<code>=default</code>这个『算是1个关键字好了』（2333，好勉强），那就可以重新获得并且使用，这个意思就是说，刚刚已经说了，如果你没有写，编译器会给你一个，但如果你写了，那么编译器就不给你了哦。那现在就是说：那我还是想要那一个，那个空的，什么都没做的那个，那你就写上<code>=default</code>，直接看例子吧。</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">Zoo</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">Zoo</span><span class="token punctuation">(</span><span class="token keyword">int</span> i1<span class="token punctuation">,</span> <span class="token keyword">int</span> i2<span class="token punctuation">)</span><span class="token operator">:</span> <span class="token function">d1</span><span class="token punctuation">(</span>i1<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token function">d2</span><span class="token punctuation">(</span>i2<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token comment">//这是个构造函数，那么从第1句就发现，编译器就不给你了</span>
    <span class="token function">Zoo</span><span class="token punctuation">(</span> <span class="token keyword">const</span> Zoo<span class="token operator">&amp;</span> <span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">delete</span><span class="token punctuation">;</span>	<span class="token comment">//拷贝构造函数，</span>
    
    <span class="token comment">//这个大家觉得很新奇，C++2.0这个叫『右值引用』（Right value reference），这个事情，我们到后面，有1讲，会讲语法，会取谈论它</span>
    <span class="token comment">//这个也是构造函数，和上面一样，这2个都是构造函数，这个叫：move constructor</span>
    <span class="token comment">//现在，告诉你，上面这2个都是构造函数。</span>
    <span class="token comment">//1个叫copy construtor</span>
    <span class="token comment">//1个叫move construtor</span>
    <span class="token function">Zoo</span><span class="token punctuation">(</span> Zoo<span class="token operator">&amp;&amp;</span> <span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">default</span><span class="token punctuation">;</span>		<span class="token comment">//新奇的Zoo&amp;&amp;叫：右值引用。move constructor</span>
    Zoo<span class="token operator">&amp;</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> Zoo<span class="token operator">&amp;</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">default</span><span class="token punctuation">;</span><span class="token comment">//赋值操作，这个是拷贝的赋值</span>
    Zoo<span class="token operator">&amp;</span> <span class="token keyword">operator</span><span class="token operator">=</span><span class="token punctuation">(</span><span class="token keyword">const</span> Zoo<span class="token operator">&amp;&amp;</span><span class="token punctuation">)</span><span class="token operator">=</span><span class="token keyword">delete</span><span class="token punctuation">;</span><span class="token comment">//这个搬离赋值，读作move assignement</span>
    <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">Zoo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span>	<span class="token comment">//析构函数</span>
<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">int</span> d1<span class="token punctuation">,</span>d2<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h3 id="_9-1-我们叫『big-five』"><a href="#_9-1-我们叫『big-five』" class="header-anchor">#</a> 9.1.我们叫『Big five』</h3> <blockquote><p><code>=delete</code>和<code>=default</code>这2个符号，这2个关键字（应该不叫这个吧，，，）<font style="background:yellow;"><strong>最主要</strong>作用到这些函数</font>身上：</p> <ul><li>哪些函数？如下：</li></ul></blockquote> <ul><li>1、构造函数	Zoo(int i1, int i2): d1(i1),d2(i2) { }</li> <li>2、拷贝构造『以及对应的，新的，我们叫（搬离构造）好了。</li> <li>3、拷贝赋值『以及对应的，新的，我们叫（搬离赋值）好了。</li></ul> <h3 id="_9-2-delete和-default"><a href="#_9-2-delete和-default" class="header-anchor">#</a> 9.2.<code>=delete</code>和<code>=default</code></h3> <ul><li>如果你写<code>=delete</code>意思：我不要它</li> <li>如果你写<code>=default</code>意思：<font style="background:yellow;">我要编译器给我的那1个『<strong>即使</strong>我<strong>已经定义了</strong>，我还是要编译器给我的那1个』</font>它的用意是这样。</li></ul> <p>在学到任何一个C++2.0的『关键字』，我<strong>都非常的有兴趣的看，C++标准库有没有用到这个新的语法</strong>。于是：我就在我的这个全文检索的工具里面，去找，找到了上面的</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710201740529.png" alt="image-20210710201740529"></p> <ul><li>『我去找<code>=delete</code>这个符号，当然，我不知道它会不会空1格，就像<code>= delete</code>这样』</li> <li>最后找到，有空1格，确实标准库有在用这个新的语法</li></ul> <blockquote><p>这边，如果你仔细观察的话，它都是应用在上一页谈到的这些特殊的函数身上。</p></blockquote> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>比如

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li>我现在要对<strong>这些特殊的函数</strong>给一个名字</li> <li>因为在某一篇文章还是某一本书上有提到，这个名词叫：Big Three，大三。大三什么，我也不知道。反正我觉得蛮好表达这些特殊的函数，哪些特殊函数？
<ul><li>构造函数</li> <li>拷贝构造</li> <li>拷贝赋值</li> <li>析构</li></ul></li> <li>那加起来不是4个吗？？不管他啦，反正当我在讲Big Three的时候，我谈的就是这一些『侯捷用笔画屏幕6个函数。。。呃』</li> <li>那这一些函数有什么特别呢？</li> <li>编译器会它加上默认的版本，除非你有自己定义的，不然编译器会为他加上默认的版本。这个叫Big Three</li></ul> <blockquote><p>再回到这里，我去搜寻的结果<strong>都是</strong>作用在Big Three身上！！</p></blockquote> <p>但是事实上，由于这个2.0有这种特殊的符号，右值引用。所以，现在应该把它名字改为<font style="background:yellow;">『Big five』</font>多了另外2个。通通都是作用在这种身上。</p> <p>额。。。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710202637719.png" alt="image-20210710202637719"></p> <p>好，那么，我因为找到很多，很难得能看到这边，在这个tuple这个文件中，这边有一些注解：</p> <p><font style="background:yellow;">比如，和move有关的，就是和copy有关的另外的2.0多出来的版本</font>，它都是作用在这种东西身上。</p> <ul><li>然后，我想去找找有没有应用在『析构函数身上的』</li> <li>不太容易的找到了，下面这个！！</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710202919899.png" alt="image-20210710202919899"></p> <ul><li>一个标准库中一个和时钟有关的新类，比较少看到应用到析构函数身上。</li> <li>这个<font style="background:yellow;">析构函数如果写成<code>=delete</code>呢，麻烦就大了。等下来看看这个话题。</font></li></ul> <p>好，我现在用各种情况，我写了一个代码在这边。</p> <ul><li>我用各种情况来让你感觉，什么时候可以加<code>=delete</code>，什么时候可以加<code>=default</code>。以及加or不加编译过不过？</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/20210710204246.png" alt="20210710204246"></p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token comment">//第1行，我定义了1个constructor</span>
<span class="token comment">//第2行说：我还要那个default constructor，注解：于是和上一个并存！！为什么呢？可以并存吗？</span>
<span class="token comment">//因为构造函数本来就可以有很多个！，，现在你看到的整体是一段通过编译的一个代码！！</span>

<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token comment">//下面这个叫作copy constructor，我写出来之后</span>
<span class="token comment">//					——如果我又写：=default的话，就表示我也要编译器给我的那个。那不行！所以我这边的意思是，这样是不行的！为什么？？因为copy constructor是不能有2份的！constructor可以有很多个，但是copy constructor只能有1个，所以，大家可以看到报错信息！它不能被重载，不能同时存在！ </span>

<span class="token comment">//接下去，如果我又写了=delete这一行的话，那也不行！！我既然已经写出来的话，我又要说=delete，那编译器又要何去何从呢？？所以，它不知道你的意图，所以报错！！</span>

<span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span><span class="token operator">==</span>
<span class="token comment">//copy assignment operator，拷贝赋值操作符，既然我写了，那么编译器默认给我的那个就不会存在，于是，报错原理和刚刚的一样！！</span>
    
    
    
<span class="token comment">//析构函数呢？</span>
<span class="token comment">//我说我要=default的那个版本，那么如果我写了这个，上面我写了它，说我不要它，那编译器又搞不清你的用途了。</span>
    <span class="token comment">//所以，这2个不能并存，只能其中一个！！</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><h3 id="_9-3-一般函数？"><a href="#_9-3-一般函数？" class="header-anchor">#</a> 9.3.一般函数？</h3> <ul><li>一般函数可以运用这2个东西吗？试试看</li> <li>如果，我写<code>=default</code>，一般的的函数哪里有什么默认版本，没有，所以写这个会报错，于是乎我们可以好好的去看编译器的报错信息是一种很好的训练。看看编译器给的讯息是不是完全能懂，或者去解释它。</li> <li>好，我再另外一个函数，我说他是<code>=delete</code>，这个倒是可以，其实我们一般也少用这个东西，因为你不想用这个函数，你一般也就没写。。写了就delete，蛮特别，但是语法是通过的。</li></ul> <p>『注意：=delete可以用于任何函数！！这个会让我们联想到，虚函数，如果我们不想在某一个类里面去定义它的话，通常，那是一个很纯抽象的类，我们才会这么去向他<code>=0</code></p> <p>一般的函数，我写=delete就是不要了，是不是和<code>=0</code>有异曲同工之妙呢？</p> <ul><li>上面就是这2个“关键字”使用的方式和语法</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710215332526.png" alt="image-20210710215332526"></p> <ul><li>注意PPT中红线的！《Effietive C+++》</li> <li>如何确认编译器真的帮我们生成这些呢？你看左边，我们没写这些的构造函数啥的，但是这样却能做，可见如果这些不存在，调用者如何调用呢？</li> <li>『<strong>藏身幕后的』：比如，子类的构造函数要调用父类的构造函数！这个调用的动作就要写在这里</strong>！</li> <li>从这2个“关键字”讨论到了“默认的版本”</li></ul> <p>连带着去想：到底怎么样的class需要自己去定义『Big Three』：我还是习惯用『Big Three』这个字眼，什么样的class不需要去定义那些Big Three呢？？而使用默认版本就够了呢？其实这是个很重要的话题，我来补强一下过去应该要有的知识点！</p> <p>一个类只要他里面带着pointer member，指针的成员，几乎你就可以去断定它：一定需要自己去写出那个Big three出来。</p> <p>如果这个类不带着那个：绝大部分，你可以断定不必为他们写BIg Three，就用默认人那套就够了。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710220136265.png" alt="image-20210710220136265"></p> <ul><li>我们找来找去，上面的，发现没有析构函数和拷贝赋值！！</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710220605111.png" alt="image-20210710220605111"></p> <ul><li>在C++的2.0中还有Big five</li></ul> <h3 id="_9-4-3个class"><a href="#_9-4-3个class" class="header-anchor">#</a> 9.4.3个class</h3> <ul><li>class NoCopy意思是一个不准被人家拷贝的。
<ul><li>其实有个设计模式叫作：单体、单件、单例模式，就是只能存在一份实物，不准人家拷贝。</li> <li>写出一个class不准人家拷贝怎么办？你就要把所有的跟拷贝有关的函数，通通不准人家调用！跟拷贝有关的，那就是拷贝构造和拷贝赋值嘛。如上PPT</li></ul></li> <li>class NoDtor，那就是把Dtor给delete掉。后果就是：对象总会有离开作用域的时候/动态创建后死亡的啊，这样编译器会报错啊。。</li> <li>PrivateCopy是对上面的NoCopy做变化，但是我们知道面向对象的时候，会有一些特殊的关系存在，就像人类世界中，特殊关系就会有一些特殊的权利。所以，我们看。比如朋友，一般人不能对你做的事情，可以对你来做！我们也许在程序中做！</li> <li>所以，我们用下面的Private，这样访问就受到限制了，什么样的人才能访问呢？那一定时朋友啦！！</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710221708742.png" alt="image-20210710221708742"></p> <ul><li>比如最后的就是不能被一般的class拷贝！当你在现实中给朋友开个小后门，就可以模仿这种手法！</li></ul> <h3 id="_9-5-boost中的手法"><a href="#_9-5-boost中的手法" class="header-anchor">#</a> 9.5.boost中的手法</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210710222340727.png" alt="image-20210710222340727"></p> <ul><li>像这样的手法，我们观察到，在boost里头就用这个手法就把它实现出来！</li> <li>boost是C++标准库的。。我们把它叫准标准好了！因为它的一些成员都是一些有社会影响力的人，尤其在C++的社群里面，所以他们会有一些很前沿的发想，做出来之后，最后经过大会讨论再一个个搬到标准库中去！！这个叫boost，它是一个C++的社群。它先前就有一个class叫做：noncopyable,我们在它的源代码中找到了！</li> <li>它的这个整个放在命名空间，叫做boost里面，在这个里面，找到了又有一个namespace叫做<code>noncopyable</code>这个单词，就用到了，『上一张PPT最后的技巧！！』</li> <li>开的后门：这样朋友和自己的member就能拷贝！！这是boost中的完整代码，我们没修过！！</li></ul> <p>所以，其实设计成这样的class，其实是为了让你来继承它！！你来继承它的话，你就有它的性质！！：</p> <ul><li>就是只能被friend和家族成员才能拷贝，这样你的FOO就能带有这种性质！</li> <li>当然，关于这个名字，《Effietive C++》的作者调侃这个boost的这个class的名称，英文不是应该叫uncopyable吗？现在叫<code>noncopyable</code>,。这是一个小插曲！</li></ul> <h2 id="_10-alias-template"><a href="#_10-alias-template" class="header-anchor">#</a> 10.<code>Alias Template</code></h2> <ul><li>本节和『using关键字有关，也就是我们的第12讲』</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>Alias Template
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>接下来我们来谈这个主题。Alias Template
Alias 呢是化名的意思。
化名就是别名啊，一个人如果有另外一个名字呢，那就是Alias ，在现实生活中呢，大概你会去想到你一个化名。
你如果听到某某人有化名呢，大概你也会去联想，他是可能是一个犯罪集团。</p> <p>事实上古人呢是有很多的化名，很多的别名啊，这个我很喜欢的一位诗人。居易他自乐天，这也算是他的别名了啊，号香山居士，又号醉吟先生，这都是他的Alias</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719192243987.png" alt="image-20210719192243987"></p> <ul><li>好，我们现在谈这个Alias Template啊，<strong>我现在一开始先告诉你，他可能你会以为他只是一个小东西，不过就把一个东西换成另外一个名称，以便方便来使用来编程，但是到后面会引发一个，呃，一一件大事情。让你吃惊了，大事情</strong>。</li></ul> <p>像这样子写。你现在看到一个关键词叫using。这个关键字并不是c ++2.0新迎进来的，以前就有了，但是2.0，还有另外的意义存在。现在这个就是一个新的意义。</p> <p><strong>这个意思是说，我现在要使用这个名称叫Vec。他代表什么意思呢？他代表等号后面这一串意思</strong>！
那由于这是一个这一串意识，这这一串是什么意思？这个意思是说我以后写Vec就说就代表我。要写成vector&lt;T,学习？并且里面。我可以指定参数。啊，就是你现在看到这个样子。</p> <p><strong>那我们就把它叫做。是这一个模板的别名alias，化</strong>名。</p> <p>怎么用呢？这样用。我就可以给定这个别名，我给定一个参数，这个参数就会放上来，变成这个红色的T</p> <p>这样带来的好处是：我以后我下次再写啊、呃，选。
我如果使用其他的容器的话。啊，我我就为其他的东西再写一些呃，这个叫这个叫再写一些大写的历史的大写的代表，用一些别名。可以很方便的让我像这么用，这是怎么用呢？
原本。vector 默认的分配器。是那个小写的呃allocate，如果我要替换我自己的分配器的话。我得写成这样子。</p> <p><strong>每一次用我多得写这么长的一行</strong>。</p> <p>这个是Alias Template带来的方便性。</p> <ul><li><p>你可能会想。你可能会想，那好像跟define 差不多，我能不能用define 来写出这种东西呢？
比如你可能会写出想要去。 『<strong>但是其实不好，你仔细看PPT下面的！！</strong>！』</p></li> <li><p>如果是typedef，发现也不是我们想要的，<strong>比如，我每次都没办法指定参数！</strong>！</p></li></ul> <p>整理一下这个ads template 是一种别名，化名，这个化名是带着参数的。你可能会想要写成下面这两样，但是这个都不是我们所要的。</p> <p>好，这对于一个化名，按理说呢化名本身就应该代表本尊本人。呃，白乐天就是白居易。但是在这个地方。</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>It is not possible to partially or explicitly spec alize an alias template.
不可能部分或显式指定别名模板。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>说<code>it's not possible</code> 不可能做什么事情呢？去对一个Alias Template做特化！『不管你是偏特化还是全特化』</p> <p>『注意，下面这句，注意点』
<strong>但是这句话告诉你，如果你给他命名为换了一个名称，你不能对那个名称来做特化啊，你还是得老老实实的对原来的那一个东西去写出的话</strong>，</p> <ul><li>你就得。不厌其烦的把它全名写出来。这是要注意的一点，<strong>化名只是化名，他其实没有代表本尊</strong>。</li> <li>那么从这个化名，你可能会误以为大概就只是让代码写的写少一点吧。你可能以为只是为了少打几个字。但难道只是为了少打几个字吗？</li> <li>下面是会让你脑洞大开的实战经验</li></ul> <h3 id="_10-1-脑洞大开开始"><a href="#_10-1-脑洞大开开始" class="header-anchor">#</a> 10.1.脑洞大开开始</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726094552299.png" alt="image-20210726094552299"></p> <ul><li><p>我现在举一个我的实战经验。这个这个牵涉的蛮多的。会让你脑洞大开。但是在整个故事呢蛮环环相扣，而且也活有点复杂度。</p></li> <li><p>那么给的画面的是。三四页而已，可是里面的故事很多啊，我们要有这样的心理准备。</p></li></ul> <p>我现在打算设计一个测试程序，测试函数要这样。</p> <p>我其实我我可以多说一点，就是我在测试我这一个元素。
他也没有写出那个C++2.0新增加的那个move semantic 就搬离的语义。然后我要来测试在不同的容器身上。效率有没有显著的提高？那我容器有有七八种。</p> <p>这样子写的话，编译器说好，抱歉还是不行。
因为你这样子写i name 的话，那么我编译器期待会有一个nested names。is five.
这是什么？就是一个差一个。刊号的勘套的一个。一个就是那个冒号冒号的意思。
只要第一次看到type name，他都因为预期后面一定是什么什么冒号冒号。这个叫堪套式的一个。
一个命名。所以他还是不认得。这样我们真的是无解了。</p> <p>我的目的就是希望做到船这种这样的东西。经过这个考量，再到这个考量，都没有办法解决问题。</p> <p>怎么办呢？</p> <p>于是，我换了一个解法。
换成这样。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726100103556.png" alt="image-20210726100103556"></p> <p>传进去的东西传给一个函数一定必须是object。
那无法可想了，我只好牺牲掉调用挖。的一个弹性。回到上页啦，我本来调用端是希望这样。
谢谢，十号把它结合起来。
给他新的这一夜。
那这样子好不好，我把我到底要测试什么样的元素放到哪一个容器去。我在这边调用端就先把它结合起来。
然后。产生一个临时对象。</p> <p>各位在看哪一页？我准备了画面的时候，都先看这个地方。
你就会知道要从哪里看起。
城市代码程序的代码呢，我都会在你该从这里看起，给上这个。
这个符号。
好，因此我就可以这样这样这样这样这样这样点点点，我可以有很多次的调用，我们就分别测试了链表。
that. 对，等等等。那每一个测试我放个元素都是可翻动的，他不可翻动的两种。
这就达到了我要的那一种。跟他的。跟这个函数的接口的关系。</p> <p>好，我们来分析看看，这样的话这个船进来这个传进来，因为这可以接受各式各样的东西，所以接受这个东西叫c。他是什么类型呢？不知道。但是他是一个模板，所以通吃。进来之后，我得去取出这一个容器里面那个元素到底是什么type什么类型。</p> <p>我在。刚刚吃一个一开始的发想里面呢。
这不必取出来，用指定的。
但是现在既然进化到这里，进展到这里了。
要想尽办法去取出来。</p> <p>好，我就灵机一动，这么想，能不能这么做呢？
把这个容器。容器一定有定义一个iterator 这样的time。这是我们对于标准库的容器的理解。如果你不理解，那这个就做不下去了。好，这是他的规格规定的容器，一定带着这样的一个to define。
所以这样就把它取出来了。
这里整个就是一个产品。
这样得到一个迭代器之后，又根据我们对标准库的了解，迭代器一定。
带着一个value type 这样的定义。
所以把这个迭代器。
再丢到这个trace。
所以说我把它叫做萃取机，这是一个机制啊，这都不是我们这一门课里面谈的。呃，在我另外一门课是一家家标准库里面对这个就谈的很清楚。
那现在这也是示范一个应用。
所以我就以容器拿到了迭代器，迭代器通过垂死得到了杯就探访南非，就tape，就是每个元素的类型啊。
所以这么长的一个名称。
我把它记下来，换了一个名字。
紫色的这个。
换成这个名称之后。
我终于可以拿它来建立。
一个一个很多个的建立元素，并且因事而到。
传进来的这个容器。
这样也算是完成的工作，间接的完成的工作。
怎么样间接完成工作呢？回到上一页，我本来其实是希望这样这样感觉更好一些。但因为做不到。所以退而求其次。这样这样当然也。也不<strong>算太差</strong>。</p> <p><strong>啊，事实上代码也没多写起啊，而且我们还好好的练习了一下这么这一行的写法</strong>。这。没有三两三不敢过梁山啊这个。不<strong>是对标准库有相当体会的人。认识的人写不出这样</strong>做。</p> <p>所以这个写法并没有。并不会比原先的设计差。
不会。
但毕竟还是没有达到我最初想要的这种接口。</p> <p>你来比对你手上讲一个上一页这个部分你就可以分析出。
原先我要的这一种界面接口感觉蛮棒的。
<strong>好了，现在这里呢接口都不太一样了。</strong> <strong>换了一种做法</strong>。
这就把这个问题解决掉。
这个整个事情怎么会跑到这儿来呢？</p> <p><strong>我们刚刚不是在谈。化名吗？alias temperate 吗？我们继续往下看</strong>。
先看右边这一段。先看下面这个。既然谈的是容器。他的迭代器就能回答value type 这种问题。我们是想知道容器里面的元素的类型就是为轮胎的。所以那这个现在这几句话的意思就是这样。
容器就有了迭代器，有了迭代器就可以问出value time。所以这样就间接间接的解决上述问题，上面这个问题。等一下我们再来看一下。但是万一这个解法不错，但是万一。万一。容器不能回答这个问题。
或者得到的迭代器又不能回答这个问题。
怎么办呢？这<strong>是一个假设性问题了，其实没有万一在标准库里面，它就是规定一定要有这一些回答</strong>。
只是我说那万一脱离标准库的。
所以。这个解法是这样很好，但是当然也要思考万一的情况。
啊，这个万一情况在标准库里面是不存在的。
现在我们看看下面这一段。</p> <p>在我知道这边你慢慢体会。
这一段的意思。就是要去探讨上叶然一开始发祥的时候，我希望的这个借口。
我希望就是传。这些容器的名称就好了。
注意这些容器都是模板，所以意思是我希望传进去的是模板哦。
很特别是模板。这就是这句话的意思。能够在模板接受一个参数，不是那个参数本身又是一个模板。
然后从中取出这个元素类型。你看这个例子就知道了。
<strong>也就是说我不死心。我还想回到最原始，我的发想我还是希望能够这样『也就是说，我想要那样的接口2021年注』。</strong>
怎么办呢？</p> <p>我们就会用到一种非常。艰深的技巧叫模板模板参数，<code>temperate, temperate parameter</code>,<br> <strong>那怎么都没有提到<code>Alias Template</code>化名的模板呢？</strong></p> <p>嗯接下去就好。看到他了。</p> <h2 id="_11-template-template-parameter"><a href="#_11-template-template-parameter" class="header-anchor">#</a> 11.<code>Template template parameter</code></h2> <h2 id="_11-0-『可以说是前面的续集』"><a href="#_11-0-『可以说是前面的续集』" class="header-anchor">#</a> 11.0.『可以说是前面的续集』</h2> <p>关于模板模板参数。实在不知道是不是该这样讲，把他直接译成中文就变成这样子的啊。</p> <p>我把模板参数。呃，<strong>被认为是一个非常艰涩，非常高端的一个模板的技巧</strong>。
哦。特别是如果，像这个就是一个模板模板参数。特别是如果被写成一行一整行的话呢，由于里头又有一些东西是可以可以省略，不写的，写不写无所谓。因此有时候为什么也不写，因此看起来特别的，折腾人。那我这边可以用，应该能够让你很简单的就明了他的他的用意以及他的写法。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726102734963.png" alt="image-20210726102734963"></p> <p>我们刚刚在上一页这边提到。已经换了这个技巧，在更上一页呢，这是我最刚开始的发想。<strong>我希望有这样的接口</strong>。
这样子写。后来经过了这一页呢，换了一个技巧了。
但是我还是不死心，这已经解决掉了，我不死心啊，一方面可能也为了技术的追求，我还想试试看。所以我再度回到这一种接口来。接受的是一个很轻的跟一个t 我还是想用这种方式把它结合起来。</p> <p>模板是一个什么样的东西？模板，由于里头有很多位，这些参数都是未定。
所以编译器在编译的时候只是编译基本语法。
他不知道真的有东西存进来，锁定绑定的时候再编译一次。第一不变的过，那是不一定了。
他一开始通过，那只是你可以想象啊，所以就是一个粗浅的第一级，通过接下来可能会有更严苛的那又要再编译一次。
所以这一个模板本身基本语法是对的。</p> <p>但是当我们传这个东西进去的时候呢。
这是我们所要的接口吗？
你回到上一页再上夜，刚出，就是从这里来的这我们要的接口就是这样子。
我的次序先对调，人数跟这个容器次序对调。
原因是这边设计的时候。
元素的类型啊，先出来下面这一个才能够使用。这里说有一个t 嘛。
啊，所以。
当我这么去使用它的时候又出错了。
这边是错误信息报错讯息。
我们来看看他说什么。
他说调用的时候啊。
第二个时差。
类型不吻合。
第一个十三就是这个了。
在哪里呢？在template parameter list。
那小心你可能一下子以为哎这里不是用v 这里什么，但list 呢，而不是这个this，这是这一句话。camper, the parameter list.
指的是。
模板参数列这一列。
有时候就是会跟。
你所认知的标准库也有一个list 的跟他混淆了。所以我特别用下划线把它画出来。
好，他说在这一个参数列里头的第二个时仓就是这个。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726103153358.png" alt="image-20210726103153358"></p> <ul><li>有没有让你脑洞大开？</li></ul> <p>我们从最前面的Alias Template看起来蛮简单的，好像只是要稍打几个字。然后我这边很快的整理，所以我现在回到前面来把这个画面。啊，我们从这一页呢，这一开始就从这里开始，我们以为就是这么化名，可以很简单的少打几个字。</p> <p>后来我开始发现。我过去的一个经验，我要做一个测试。我需要有这样我想要有这样的接口。
但是经过一些天方夜谭之后呢，发现很难实现。于是到这到这里呢，我换了一种方法。用指针。要迭代器。
但我还是不死心的。</p> <p>我这一页一页的下去啊，我还是不死心的。再回到前面当初的接口来。因为我这觉得这样的接口很漂亮。一方面也是磨练技巧，于是我们要用到。can create template help me. 来完成。
但是搭配这一种说法。我们要需要终于又回到一开始的主题了。我们需要这个Alias Template。才能够。整个。
严丝合缝的结合在一起。</p> <ul><li>所以整个Alias Template呢并不是如你可能一开始所想象，只是少打几个字而已。
他确实是有大的用。</li></ul> <blockquote><p>下面是来自：12的开头</p></blockquote> <ul><li>我们在整个这个复杂的这个例子里头。这个测试程序。让大家脑洞大开的这个测试程序，从最前面的发饷，后来经过这非常曲折。最后到这里。这个测试程序呢会后面还会出现。</li> <li>因为我们在谈到moveC++2.0新增的新增加的一个一个有一个庞大的组合啊，他又有语言的部分，又有标准库的部分的这种叫做move的语义semantics 语义。</li> <li>啊，对于标准库容器带来的效率的影响就是用这个例子的这一个测试程序，所以后面还会再谈到。</li></ul> <h2 id="_12-type-alias-noexcept-override-final"><a href="#_12-type-alias-noexcept-override-final" class="header-anchor">#</a> 12. Type Alias, noexcept, override, final</h2> <h3 id="_12-1-type-alias，类型的化名"><a href="#_12-1-type-alias，类型的化名" class="header-anchor">#</a> 12.1.Type Alias，类型的化名</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719144703013.png" alt="image-20210719144703013"></p> <ul><li>比模板的化名简单多了。『类似于typedef』</li> <li>『其实是using关键字』</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>There is no difference between a type alias declarationand typedef declaration. This declaration may appear inblock scope, class scope, or namespace scope.
类型别名声明和typedef声明没有区别。该声明可能出现在块范围、类范围或命名空间范围中。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><ul><li>这个<strong>也是借着using关键字</strong>导出来的。黄色和下面的是一样的意思，写法等价</li></ul> <p>好，刚刚提的是alias template 的模版的话。这个主题呢，Type Alias类型的化名。这个就比刚刚那个简单简单多了。呃，他跟那个本来也很简单，化名很简单，只是在后来发生在应用上呢，它有一个你想象不到的应用。那这个呢。这边有个小标题，类似于typedef</p> <p>好，我们看怎么用，这个也是借助using 这个关键字来导出来的。这是一种用法。</p> <ul><li>上面的这种语法不是那么能够凸显出func是一个类型，这个事实会出现。</li></ul> <p>这个人一看啊，这到底是，这是一个函数名称吗？还是什么的啊？改成这样就明确</p> <ul><li><p>PPT上左右『是这个的2种用法』</p></li> <li><p>第三种呢这样『指着左下角的框框』这个就是刚刚介绍过的alias template.</p></li> <li><p>我要引导你去看的就是标准库的这一个头文件。恨这个头文件里面都带着这样一个产品。其实用意作用就好像上面这个是一样。『指着左下角的框框的下面』</p></li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719145313530.png" alt="image-20210719145313530"></p> <p>现在我的这一页把所有using这个关键字出现的可能性通通收集起来。刚刚在上一页你已经看到了，这有三种可能嘛。</p> <p>除了这三种之外，还有不过这是不是新的东西啊，这是本来2.0之前就已经有了，到时候我把它整理起来，全部放在这里，你会更清楚。</p> <p>第一种叫using directives using the 命令。
这个是我们我也常常用的，你要把std打开。我我口语喜欢叫他把它打开，好像好像打开了，那还上门的意思。
这是uc。
第三种呢，using declaration for class member. 你可能在class 里面。由于c 加加他在找你写出一段代码，写出一个名称的时候呢，写出一个名字，他要去找出来。他到底如果他到底是当初在哪里定义的，他有他一定的搜寻规则。如果你想避开那个规则，不只是说你在写代码的时候，你很明确。你把它写明白，让你自己以后看的很清楚，这样也可以。那你就可以像这样子。在某一个class 里头说。我要使用这一些这些这些这些，那么后面继续写代码的时候，就可以只写这个名称了。联系就知道你所写的这个名称，其实就是在他要到这一次里头去找。
下面又是一个例子啊，这太多了，这整个标准库里面太多了，这些就给归类为这个第二类。</p> <p>那第三类。就是我们前两个主题谈到的，一个是Type alias。一个是alias template</p> <h3 id="_12-2-noexcept"><a href="#_12-2-noexcept" class="header-anchor">#</a> 12.2.noexcept</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719145724311.png" alt="image-20210719145724311"></p> <p>我们继续往下看这个主题。noexcept
except就是异常。我知道在很多的初学者，初学者大家根本就忽略这个问题。
那么即使业界很多工程师呢，也不一定会去，工作上啊，在公司的要求，这个项目里头就没有去碰触到exception。</p> <p>其实exception 是一个需要注意的话题。
exceptions是个大学问，我有另外一门课讨论专门讲exception，异常。
一个时数比较短的一个课程。</p> <p>那这个地方它是这个是C++2.0的一个新语法。借由这个语法我要带一些关于异常的观念。
它的用法是这样，啊，<strong>你在函数的后头写上这个关键字，意思就是说我保证，这个函数不会丢出异常</strong>。</p> <ul><li><p>事实上这一个，是可以继续加上小括号——给一个条件：是说在符合这个条件之下呢，我这个函数不会丢出异常。</p></li> <li><p>所以左手边这样写，相当于是右手边是这样，直接给出，那就一定不丢异常啊！这其实是可以有条件的。比如下面这样，这就是有条件，下面这些函数就是swap交换。</p></li> <li><p>他说这设计这个函数的人。说：<strong>要表达说我这个函数呢，保证不丢异常，但是有个先决条件，是这个函数不丢异常的话，我就不丢异常</strong>。</p></li></ul> <p>我们现在没有要去讨论他的逻辑，为什么要这样设计，不过我只是展现这个语法。啊，是可以有条件。</p> <p>呃，函数后头大括号的前头。大括号就是<code>function body</code>，本体在这两个中间语法上可以放什么东西，放这种东西。
在2.0之前，你还可以指定一个叫做<strong>异常明细表</strong>或<strong>异常明细列</strong>或者<strong>异常规格</strong>。
他的英文叫做<code>exception spack</code>, 你可以翻译成规格，也可以说他是明细，也可以。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719151952827.png" alt="image-20210719151952827"></p> <p>就在那个地方，你可以很清楚的指出来我某一个函数。<strong>丢不丢异常，如果丢的话，丢哪几种异常？这个是以前就有的。新增加是这个关键字</strong>。我们来看看这一段说明。
说这一行的意思就是要宣告声明说，父呢，不丢出异常。我们继续往下看，如果有一个异常，没有被覆处理的话。异常一定要被处理啊。异常的概念是这样。</p> <p>所以异常是一定要被处理的，不然就要一直往往源头跑，最后就会跑到哪里去了。
这整个故事是什么？如果有这个地方发出异常，一直没有被处理的话，一直往上层调用。这个叫<code>stack on writeing?</code> 一点这个动作啊。一直往上传递过去，而都没有人处理的话，最后就程序就了就中断，执行不下去。
那么<strong>关于异常呢，其实在整个标准库里面，对于他哪些动作会不会抛出异常？</strong></p> <p><strong>有很严谨的规定，我刚说异常是大学问。</strong></p> <p><strong>那我要提跟我们切身有关系的，就是当我后面再谈到一个大主题叫move，move semantics</strong> <strong>当你写出这种东西的时候，你才具备一个叫做move semantics， move的语法语义。你看这是我我写的一个克拉。</strong>
我有这两个。那现在是说。谈到这一个主题。
是说你这两个写出来不止写出来哦**，你一定要加上noexcept**
你如果不加啊，加不加会带来什么什么不一样呢？</p> <p>看看这段文字。现在我们只是从这个地方出现的。我说。
你必须通知C++，特别是vector，当你在使用各种容器的时候，特别是针对vector。你必须通知他。说你的这个他这个。不丢异常，就是下面这两个。你通知他之后，那么这些特殊的函数。
各位2.0之前从来没看过这种函数，这种特殊的函数。</p> <p>才会被vector成长的过程中调用。</p> <ul><li>vector要成长，所以可能需要搬动，</li></ul> <p>就以这个vector例子，他非常经典。因为他会成长，**其他的，等一下我会谈其他的容器的结构，没有成长这个动作。**成长的过程里面，刚刚提到说会找另外一个空间两倍大。因此原来的所有的元素都要copy 过去。</p> <p>那这样拿实际的例子才能说，现在只是谈语义语法。所以在这个class 里头。我这是字符串，我宣称我认为我有一个特别快的搬动方式，所以我就写出了这个特殊版本move的语义，给我呈现出来了。</p> <p>vector 才放心的来调用这个特殊版本。
说你你写出来通知他就写出这个那么。
他才会被调用方那个成长值。
<strong>如果你的constructor不是noexcept，vector就不敢用它，这边写，说不能够使用它，也就不敢用他的意思</strong>。
这一定两者之间。好，<strong>vector 一定有一些考量啊。我要用你，你万一抛出异常，我就没办法处理。所以你要让他放心，他才会去调用。这是跟我们非常切身关系的。那我们谈到异常的时候呢，他是一个大的话题</strong>。
那是对于这个关键字，特别跟我们2.0里面的move有关。
搬离这个效率提升有关的是用在这个地方身上。</p> <p>所以到目前为止，只有vector会大幅车会成长，成长会很痛苦啊。要做大量的搬动。
ok 所以这样我们就很理解这段话了。为什么特别谈到。</p> <p>啊，那是不是只有我们特别只要要用在vector身上，我们才要去注意这边写noexcept。呃，这样讲也对啊，现在也对。但是你在设计这一个class的时候，你并不知道你的使用者是要把它放到vector里面，还是放到list。还是放到dequeue里面，你不知道啊。我们是设计不能去想到后面。啊有有一种特殊用法，那我们就少写几个字吧。
当然我们不会这样。</p> <p><strong>归纳出来就是。你的class 如果有move function，一定要注意，不要抛出异常。而且这里面，你得写出noexcept</strong> <strong>让别人用你的时候也很安心，他知道你你也不抛异常</strong>。</p> <h3 id="_12-3-override"><a href="#_12-3-override" class="header-anchor">#</a> 12.3.override</h3> <p>再来我们谈这个主题。override这是一个很小的主题。
<strong>override就是复写、改写。应用在虚函数身上</strong>。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719154444484.png" alt="image-20210719154444484"></p> <p>好，我们看看这里有一个父类。
这里呢有一个继承关系。父类有一个虚函数。
子类呢想要去对他做override。
override结果不小心写错了。</p> <ul><li>所谓的<strong>override 一定是要函数的签名完全相同</strong>。 这里呢？不小心写错了。</li></ul> <p><strong>那就不是override。那就是他自己声明了一个新的virtual function去了</strong>。所以你本意上。子类这一边本意是要去做override动作，但不小心写错，以至于不是override，是一个新函数。整个打乱了，他们弄错了你的设计。但是编译器不会告诉你。因为这当然呢，因为编译器哪里知道他不是你肚子里的蛔虫啊，他怎么知道你想做什么呢？他就认为你想有一个新的函数。现在2.0增加这个关键字。让你。</p> <p>现在写一个子类。你在想要做override 的时候呢，你在后头加上override。帮助编译器啊，你把你的心意告诉他。让他帮你甄错。
这所以<strong>你的意思是说，我就是要override他，但是我不小心这里写错了，那编译器会这边会给出这样的报错信息</strong>。
他说你已经mark，你已经标明了，你要override，但是其实你没有override。就是用在这里。把你的心意告诉引起，让他帮助你。</p> <p>好，这边还有一个对override 的注解，就留给你看，其实他的本意我们已经讲得非常清楚了。很小的一个语言上的与语法上的新的关键字。</p> <h3 id="_12-4-final"><a href="#_12-4-final" class="header-anchor">#</a> 12.4.final</h3> <p>再下来又是一个很小的东西叫final。这也是一个关键字</p> <p>用在什么地方呢？</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719154828205.png" alt="image-20210719154828205"></p> <p>两个地方。</p> <ul><li>这里有一个父类。
这边有个子类。他继承了这个嘛，继承父类。如果你对于父类写上final，你是父类的设计者。你写上final 意思就是说。<strong>我就是这个继承体系之下最后的那一个，不要再有人继承我了。我是final</strong>。</li></ul> <p>你写出这样之后，注意这关键字的位置啊，在落在这个位置上。
你这么写之后，如果有人要继承。编译器报错。这是第一种用法。</p> <p><font style="background:yellow;">第二种用法呢是用来修饰virtual function，说它是final。</font>
那个就是针对类这个是针对现在是针对虚函数。那意思是什么呢？
这个类本身可以被继承，没问题。
但是被继承下来之后呢，虚函数不可以被重新，不可以被被override，不可以被复写。这个字跟刚刚那个关键字，如果我们把它合在一起啊，这个让大家，注意。</p> <p><strong>这个final 的用法是说不允许被覆写</strong>，但是如果你在下面哦，且override意思是告诉编译器，我就是正在覆写上面的一个。</p> <p>这是两个关键字，他们的意义上的差别。</p> <ul><li>所以这些都是帮助我们让编译器。帮我们检测，不要我们一不小心写错了东西。
<strong>像这样的关键字其实蛮好的。在面向对象语言</strong>。啊，其他的语言，已经发展出蛮多了。比如说java 也都有这些东西，也有abstract 这样的关键字。</li> <li>C++还没有目前。abstract 抽象的。等等等。</li> <li><strong>也许我们可以一起在C++2.0之后更新的版本会有更多这一类跟面向对象跟class或虚函数的设计。相关的一些方便的关键字</strong>。或许我们可以预期这样。</li></ul> <h2 id="⏳13-decltype『关键字』"><a href="#⏳13-decltype『关键字』" class="header-anchor">#</a> ⏳13. decltype『关键字』</h2> <ul><li>现在我们来谈这个。新的关键字，能不能说它是个关键字呢？其实也不是啊。</li></ul> <p><strong>他你看到，他在用他的时候有一个小括号。有时候对于关键字或者是呃呃他是标准库里面的一个零/组件、一个部件呢，这已经不是分的很清楚了，其实也无所谓</strong>。</p> <ul><li>有一些程序员啊，一些朋友对于这个C++2.0的一些新特性的评价，对他说有，有蛮多的一些关键字呃，叫什么？把这个也当成关键词好了。</li></ul> <p>这些关键字呢啊好像也其实主要是用在标准库的设计上。标准库为了让他在发展的过程里面需要一些东西，于是有语言的部分语言这个小小。主们就提出来来来设计来。
嗯。包括现在要谈的这一个叫decltype，也是刚刚我所说的这一种评价的范围之内。就好像这个是专门为了设计库为了设计库大小的库而准备的一个新的特性，<strong>我不是很认同这种说法</strong>。也就说我们在进行编程的时候啊。
我们难免也要写一些像库之类的东西啊，就给别人用，给自己用，给将来用就是一种library，一种库。</p> <p>呃，甚至于你只是写一些，不是拿来当成library 的一些代码啊，但是你也是会需要用到一些高阶技巧。这个在我平时写很多的测试程序的时候，<strong>也都会你为了想让你的代码更漂亮，更精进</strong>。
<strong>你都会想要去用到一些新的技巧，所以并不能够说啊这些东西就是为为了开发标准库而准备。我们一般人用不到，我们也不要把自己当成一个凡人</strong>。
在再者呢呃我总是觉得你要好好的用C++的话呢，你对于标准库啊能够去阅读他的一些源代码其实是很有价值的提升你的技巧，所以要能看得懂，你知道吗？你就会看到这一大堆这种这种这种新的特性。</p> <p>好。在谈这一个decay type，这个我找了很多的文献的资料。呃，网络上的东西了，我总是尽量的提醒我自己啊，能够在找到什么。哎，这一段很有价值啊，很值得跟大家提的时候呢，要记得把他的出处写出来，像这个我都要写出出处。这边我都要写出出处。</p> <p>万一在整个课程里面有一些疏忽的地方没加上出处了，那还真是抱歉。所以这个原则别人作者一个无心的过失。好在这。</p> <p>我现在准备了这些文字里面呢，我不带各位一一的看。我现在要谈的是这一段，其他的呢你就自己体会，你手上也都有奖励，你自己体会。</p> <h3 id="_3分钟开始"><a href="#_3分钟开始" class="header-anchor">#</a> 3分钟开始</h3> <p>我要看的是这一段，我们来看看啊。这段说。使用这个新的decltype这个关键字在这里达到那个关键字，你可以让编译器找出来，找出什么呢？一个。expression the type expression 表达式。这你有一个表达式，你想要知道他的态度，他的类型是什么？
那你可以用这个来找，所以这边继续说了。this is 这个呢很像是我们常常对于他off 负的需求。
还好。
在c 在家里面只有太保id。
搭配有一个头文件叫做time in four。
have information 的意思。
害怕id 搭配那个头文件，你就可以得到一个。
所以吸氧另外一个对象传进去，一个object 传给他，传给太保id 这一个函数你就能够得到i d i d 就是一串字符串。
但是这个字符串你也不能拿来做什么用没有，只是可能打印出来让你感觉一下而已。
你不能把那个东西又当成一个类型，一个tape 啊来来做实在代码里面继续做事情不行。
而有时候我们是需要一个tap of。
一个表达式为一个对象，他到底是什么？
tap 呢？
想知道，而且知道以后拿来继续编程要用。
一直以来长久都有对这个东西的需求。那么呃西有路c 加加啊有提供太好。
但是这不能算是一个标准的东西，因为孙佳佳标准规格书里面没有提到这个。
啊，所以现在所介绍的这个呢就有这样的一个功能存在。再看例子你就会看得出来。
这边继续说了，然而已经存在了这个胎奥。
呃，这个实现它指的就是耿共十一里面的那一个实线。
啊，是并不完整，也不是这个很一致的。在c 家家里头，其实他们就是我刚刚讲的就是他不是标准规格的一步。
所以c 加加eleven 是就在二点零呢导入了一个新的关键字，怎么用啊？像这样子用。
这个例子。
呃，好，现在这边有一个。
类型这边创建出一个对象。
我现在手上有这个对象了。
我想要知道这个对象的太不是什么，我们当然不会在代码里面写出这两行，也太不就是商银行嘛。我们是说这两款可能分隔的很远的地方。
这个对象呢也传到了，不知道一个函数呢还是一个是一个函数模板里头去了。
在某一个时间点，某一段代码的某一个位置，你得到的一个对象，你想要知道它的在一起，那就可以这么用。
你知道他的类型像这个例子是说啊，你知道这个对象其实是一个容器，只是你不知道是什么容器。
但你知道容器一定有定义，一个探索叫value type，这是你所知。
你所知道的，于是我就用这个容器呢丢到他就知道他的类型了。
通过这个类型就可以取得它里面的一个time define。
这个。
那这个菜比率的把整个这又是一个type long。
然后我们可以拿来做事情了，我们的代码里面继续可以做事情了啊，我用这个tab 呢声明一个变量。
这样就可以。
呃，如果是在c 加加以eleven 之前，二点零之前呢，你就没有办法通过对象来取的态度。
必须知道那个对象啊是什么，本身是什么类型，你必须确实知道，你就必须这样写。
那咦我刚刚说怎么描述里面的描述，你知道我们有时候只得到对象，你不知道他的类型。
好。
所以对于这个deck type 这个关键字啊，你把它想象他代表着type of 那就对了。
这是特别容易想象的一点。
那么这个东西。
的应用呢？
这里我把它分成三种。
这三种在后面都会一一出现。有例子。
b.
好，这一部分。
我把这个字放的比较大。
这是下一页。
啊，我把上一页最重要的一些智能重新抄到这边来。
现在我们再看一次这一个关键字，就是用来定义一个tab。
这个菜粉呢是等同于一个expression，一个表达式的类型。
这个刚刚说过了。
这一段呢刚刚也说过了，他相当于一个菜哦。
下面这一段呢就是财政跳过来要看的这个东西的应用有三大应用。
好，我们一个个来看，现在也不必去看这些文字了。我们开始一个一个看。
第一种应用。
是用来。
宣告为生病一个return time。
比如这个例子。
挤压。
一般来讲，我们会把积压标准库也会像我现在所说的啊，家呢设计为一个模板函数。
所以加什么东西，加a 跟b a 跟b 是同类型的整数。
两个都是整数。
字符串两个都是字符串，石头两颗都是石头。
那因此那种设计上只有一个模板参数。
但这个呢。
不一样了。
他接受x y x 跟y 是两个类型不一样哦。
两个类型。
所以这个意思好像是。
你把。
青菜加上萝卜。
那你搞苹果加上离子。
这就是类似这样的意思。
那这两个东西就是变成这个执行结果是x 加y 吗？
这里头这只是一个声明，它里头的动作就是应该x 加y。
小歪，这苹果跟梨子能不能相加？这要看你对苹果的设计跟对离职的设计。
你可以说这两个都是水果，加出来是两颗水果。
人类的世界上，我们这样子想好了，或者你说啊诸如此类的啊，青菜家萝卜就是两种。
蔬菜。
所以能不能相加是你对于这个希望跟提出的设计，说不定他们可以转型啊。梨子也是水果，呃，呃苹果也是水果。
所以啊他们都有一个共同的父类，他们是可以相加的。也许你这样设计。
好，但是ok。
那是x 加y 的动作，可是这个艾的这个函数本身他总要把他自己总要设计出来。他的加完之后的类型是什么，中要写出来。
现在在设计这个模板的时候，完全不知道希望跟地图是什么，说不定他们不能相加。
说不定他们可以相加。
所以。
c 嘉嘉的这个关键词就出现了，呈现一个很棒的作用。它允许我们去说。
带着的返回类型到底是什么呢？是x 加y 之后的结果的类型。
这个你可太好，刚刚的那些文字里面有提到。
他是让编译器去。
找出来找出什么一个表达式的结果的类型，这个就是表达式。
那这个执行完之后。
他到底是什么类型呢？aac 你帮我推一下啊。
写出来就是这。
所以这其实模板啊模板是一个半成品。
这个c 嘉嘉的面向面向对象这一个特性呢已经。
行之久矣啊，也很成熟了，就是更多的发展都在模板上面的标准库，整个又是一个大魔。
模板只是一个半成品，就像现在这样子这样子写出来编译就是主要就是让编译器通过。
至于将来真正去调用add 的时候。
如果你传的是。
一个人跟那颗石头作为这个x 加y，那你知道在现实生活中人跟石头是完全不对等的东西嘛，一个是生物，一个是一个矿物啊，你怎么想？
也都没有办法想他可以相加。所以那个真正的用他的时候会报错。
这个地方。
x 加y if x 根本不能跟y 相加，是这时候会报错。
但如果不是这么用，而是蔬菜加水书。呃，苹果家离子的话很可能就通过了。
所以这只是一个半成品，他到底最后。
会不会通过呢？要看你怎么去用啊。
啊，这就是这一个的妙用。你可能要毯子的不用。
但是当写成这样，我们的理解直觉一开始的想法是写成这样子。
可是呢当编译器编到这里的时候。
编不过因为编译器是从代码这样从上往下编嘛，从头往尾巴边。当他跟到这里的时候，他没有看到x 跟y。
xy 是在后来才出现。
所以这是一个小插曲。
这样子写在意义上是对的啊，但是鞭不过因为先后次序的关系。
所以怎么办呢？
c 加加二点零又出现一个新的语法。
特别针对现在这种情况说那这样好了。
这个函数。
他的返回类型是什么呢？
oto.
oto 这个关键字，我们前面介绍过。
呃，是很独特的，在这里用的。以前介绍otoo 是说你有一个对象。
你要给他设置以后，但是你不想写出他的态。
你用oto 回忆一下。
这里也是完全不同哦，这里是说这个函数的返回类型是什么呢？啊，暂定我不想，我写不出来，所以说oto 不过我在后头就必须写出来了。
在这个地方啊是关键字，特别加上这个符号。
那写出来是什么呢？其实刚刚前面你已经写出来了，只是因为先后次序的关系呢，他编译不过就换这一种写法。
这就是我们的第一个用途。
回到刚刚那一夜，这里有一二三嘛。第一个用途就是用来声明。韦珍time。
返回类型。
就是这里。
所以我们在这个例子里面不但认识了。
你可能也太狠这个关键字，而且要认识了一种新的函数返回类型的。
指定方式。
啊，改用oto 跟这个箭头。
好，那这一种指定方式呢？汗。
浪的。
指定方式一下。
等一下我们就要提到浪的，那么呢就是一个。
一个函数啊，一个临时马上要写出来一段函数呢，那不用给他名称，没有名称。
的函数。
好，这部分呃主要是取得说这一个表达形式oto 跟这个箭头符号的表达形式很烂的。
要表达的很像。
倒不是说这个可能也太不够那么的，有什么关系？
注意这一点。
这个黄色的这一部分，这个是这么大的。
全完整式的语法。
等一下我们就要来介绍这个下一个主题。
这是第一个用途。
我们继续往下看。
我学到任何一个c 加加的新的语法，我总要去看看标准库有没有开始在使用它啦。能不能我从标准库里面。
汲取一些痒。
这边。
c 加加呃，德穆斯一家家四点九版的标准库里面大无处都是这个。
四点九百并没有什么很特别，我只是因为我手上的已有，而且他是支持二点零。
找我，我看见一个。
很多。
我前面介绍过一个全文检索工具啊，是这找出来这么多这么多这么多这么多理念呢，我随便挑一个来看。
这个是plus。
就是跟刚刚那个我们的例子很像嘛。这add 相加the plus 也是强加这里面他也是用到oto。
然后这里有。
相加这里有有有一个箭头符号。
跟刚刚再看一眼刚刚我们的这一个呢完全一样。
好，回到这里来，他一个oto 一个箭头符号，然后后面呢有可能要态度。
好，继续往下。
第二种形式。
是说回到刚刚前面讲第二种形式是什么呢？可适用于make up programming。
听起来好像很伟大，因为他programming 可能被翻译成圆编程。
其实就是在模板里面的各种。
各种运用各种操作啊，就是这样而已。
他们make up programme。他本身有一个更高级更更更高级的规格的定义。我们就不去谈他了。
也不过就是这一个在这本书里面的这一段里面用到的没他们这个字一样啊。所以现在我来举例子，现在回到这里。
第二种用途。
好，我现在这里是一个什么？我整个。
是一个函数模板。
刚刚那个文字里面提到的没他programming。我说你要想的太严肃啊，不过就是模板之间的运用。而现在呢就是一个函数函数模板。
这个函数模板。
接受一个对象。
这个对象的太和是t。
那现在这边所写出来，当然我如果想知道obj a 的类型是什么，那就是t 我可以拿来直接用。
但万一没有这么直接啊，他继续模板又掉了，要去等等等啊。终于在某一个时间点，你得到一个对象。
但是你不知道他的类一起。
可是你想知道他的类型怎么办呢？就类似。
这个样子。
这样。
obj 就这个我有一个对象，我要知道他是什么类型。
知道了之后。
由于我的这个。
这里面的设计我已经知道传进来的必须是一个容器。
一定他是一个容器啊，所以我知道这个类型之后呢，我连冒号冒号取得他的迭代。
因为我知道容器一定有迭代器。
好，把这么长的名字。
只要加上冒号，冒号，注意前面就要加谈判name。
这是帮助编译器去确定，这整个确实是一个part name。不然他会有点犹豫。
因为只建议这一段的时候，obj 是什么还不知道呢？
好，这整个这一个重新换了一个名称太长了。我昨天换了一个名称叫ipad。
然后这个ipad 壳膜就可以拿来这下面代码在编码的时候继续的使用。
这样我们就是说这这一个关键词的第二种用途。
刚刚第一种不太一样形式。
用法都不太一样。
那上面这些是什么？其实故事跟下面这个完全一样。
所以我就不谈了，这边有一些注解也可以也许可以对你还有另外一个角度的帮助。
好，这个是第二种用途。
我这边提了一个问题。
这个人在请听那种状态。
如果使用者去用这一个函数的时候，这是一个模板函数使用它呢指定进去的是一个复数。
这是产生临时对象。
复数一个临时对象家传进来这里的obj。
传进来之后，obj 这个地方呢要去取得obj 的tab，那也就是复数喽。
然后要去取得负数的迭代器。
复数没有迭代器，这个地方就打叉。
我再一次提到刚刚已经说过的一个概念模板，只是一个半成品，这样是编译通过。可是用的时候用错。
过了。
那仍然。
就最后整个要再编一次，还是会报错单独的这一个模板是对的。
当然在设计这一个模板函数的人，就应该在前头加上很好的注解。
说传进来的obj 应该是个容器。
那这样的话呢，调用的人如果有仔细看注解的话，他就不应该把非容器放进去。
有没有什么强制性和这个一定要是个容器哦。
啊，非溶剂存进来会使我是要把它剔出来的呢。
嗯。
这个要细想一下。
一般不太会去做这种事情啊，只会在注解上面做说明，也许可以。
用编程的方式去禁止这个这个这备用意思。
也许可以这个这是我讲到这里的一段插曲。突然想到这一件事。
第三种用途。
三。
第三种用途。
好，我这边应该打一个bud 三，这样子就能够更帮助你。
我们刚刚我们回到上面来看。这是二嘛，这是一在最前面说一个二。那第三种是什么？pass, the type of a long.
好，我们来看到三怎么样来表现。
就是这里就是三。
那么早是什么呢？终于第一次看到了浪漫的长相，是这样子这一块。
中国号骑手的东西。
那个语法非常的奇特。
对于也许呢嗯没有继续跟上c 加加二点零呢，也再过几年的，这个是在家代码一看都看不懂，太多奇奇怪怪的符号，这个其实也类似这个pass square。
程序员呢他进入c 一的时候，还不要讲c 加加他进入四一的时候，他就看到一些什么箭头符号了，星号了这些这些奇奇怪怪的服务。
好一样，现在呢也是奇奇怪怪的符号出现。
用中括号来表现啊，反正现在我们先认识，这样就是一个浪的。
那么他是什么呢？一个函数。
这个函数。
将要用这一个东西来表现，这是一个对象。
啊，所以。
继续写下去试验b 就表示这一块。
就要执行这一块。
那时nb 是个对象，他的tap 是什么呢？哇，很少人能够写出那么大的态。
我们通常也不太在意，所以就用oto。
好。
那接下去你可以开始使用体验mp 啊，这里cmp 是come here are 的意思。因为这里在做比较动作，所以把这个命名为here are。
接下去的动作呢，如果你只是要用一个对象，这个对象的话ok。
等下会真正讲那么大，你会看到怎么去调用它。
其实就是用小括号一个方小括号叫做方兄或函数调用的一个操作服务嘛。用小刮好吧。
但是有时候我们会需要。
不只是需要这个对象，我们还需要这个对象的类型。</p> <p>例如这种。
在赛特里头。
容器set。
你想指定一个自己的一个比大小的一个ctr 有一个准则，这是一种函数了，怎么样比大小你要写一个函数来告诉。
告诉告诉这个set。
你如果不告诉他呢，他自己有一个默认的比大小的方式。
现在你想要告诉他，我要这样来比大小。
这里不但要把餐，把这个对象传进来。
你还要把这个对象到底是什么类型，也要告诉他。
这是这个set 在接口设计上，他需要这个。
所以就是这一条。
这个常见的。
那怎么办呢？这个类型没有人知道啊。
让编译器去伤脑筋，我们加上可能也time。
也就是前面讲的太饱哦。
那编程历史以来，一直大家都想得到他off 这个工具，这一把屠龙刀啊一直都没有的吃上去了，这个就类似。
好。
这就是第三种应用。
那个time。
三种。
刚刚提到了那么早。
所以接下来呢我们就要来看一看。
那么呢这个有一些奇特的符号所构成的东西到底是什么东西？</p> <h2 id="⏳14-lambdas"><a href="#⏳14-lambdas" class="header-anchor">#</a> ⏳14. lambdas</h2> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719185848169.png" alt="image-20210719185848169"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>C++11 introduced lambdas, allowing the definition of inline functionality, which can be used as aparameter or a local object. Lambdas change the way the C++ standard library is used.

A lambda is a definition of functionality that can be defined inside statements and expressions.Thus, you can use a lambda as an inline function. The minimal lambda function has no parametersand simply does something:

C++11引入了lambdas，允许定义内联功能，它可以用作参数或本地对象。Lambdas改变了C++标准库的使用方式。

lambda是可以在语句和表达式中定义的功能的定义。因此，您可以使用lambda作为内联函数。最小λ函数没有参数，只是做了一些事情:
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190128198.png" alt="image-20210719190128198"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190155412.png" alt="image-20210719190155412"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//ce
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190246783.png" alt="image-20210719190246783"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190359074.png" alt="image-20210719190359074"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190509431.png" alt="image-20210719190509431"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//测试
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190829085.png" alt="image-20210719190829085"></p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>//
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210719190630402.png" alt="image-20210719190630402"></p> <h2 id="✅-可变模板参数系列"><a href="#✅-可变模板参数系列" class="header-anchor">#</a> ✅ 可变模板参数系列</h2> <h2 id="_15-variadic-templates-1"><a href="#_15-variadic-templates-1" class="header-anchor">#</a> 15.<code>Variadic Templates</code> 1</h2> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726165017113.png" alt="image-20210726165017113"></p> <p>好。啊，我们这个第一讲的语法的部分了。我们终于要进入最后一个环节。</p> <p>而这个环节在一开始我也提过了，<strong>这是一个震撼弹。最大的一颗震撼弹</strong>。重回核暴。</p> <p>呃，在前面那个是一开始是这样的安排哈，首尾相连，一开始给大家一个感觉说C++的2.0的新东西，这个新东西是非常重要的。</p> <ul><li>所以他一开始就安排给大家概念，现在我们重新回到这个地方来来讲的更深入一些。</li> <li>并且我要带到七个大的例子，让大家。彻底的感受这个东西。</li></ul> <p>那</p> <p>他是这一一大堆这种类型。而这个类型呢，我这边都有颜色，所以你非常好区分。那这类型是什么呢？它是一大堆类疫情啊，所以在模板这一行。这个点点点要写到这里。</p> <p>他们在这个关键字吗？所以<strong>这个点点点的位置要也定要很巧妙的区分</strong>。
那这一个表示有很多个时餐，这个东西将来拿来用。
他的递归调用的时候啊，很多个时辰拿来放进来，这时候边点点又放在后头，这个是在前头。</p> <p>这个我也没有什么好说的，其实可以，你个人可以去整理出一些你的想法，帮助你记忆。
这个在你自己练习写十个，其实你也就静下来了啊，点点点在三个地方位置不太一样，有的在前面，有的在后面这个我。
<strong>也就不去为你归纳了。没有道理可言，反正语法就是这样规</strong>定。
当然<strong>他有他的道理啊，我可以归纳出一些帮助你记忆的东西。不过现在没有必要去谈这个了</strong>。</p> <p>每个人有自己的记忆方法。</p> <h3 id="_15-1-开始7大"><a href="#_15-1-开始7大" class="header-anchor">#</a> 15.1.开始7大</h3> <p>好，这就是他的基本语法。接下来我准备七个大例子。我们来看看。</p> <h3 id="_15-2-例1"><a href="#_15-2-例1" class="header-anchor">#</a> 15.2.例1</h3> <p>第一个例子。这些都是完整的，我觉得我测试过的测试结果打印出来。所以你可以比如说你现在看到例子一。
你可以把这些这里所出现的代码全部把它。打到你的。程序去。好了，我付给你的代码。</p> <p>我们整个课程有一个范例，程序里头也有这样的代码，你把它编译一遍也可以。自己打一遍。
其实也蛮好的。</p> <p>课本合起来，这个video 看完了。讲义放在一旁，凭想象力呢凭着你的记忆再打一遍哪几个字啊？
你能够把它正确写出来，表示你功力就达到了一个水准。</p> <p>我现在的设计是这样。这里有一个函数模板函数。我要用它来接受各式各样的参数。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726170000640.png" alt="image-20210726170000640"></p> <ul><li><strong>侯捷说：PPT中左边这2个函数是重载overload</strong></li></ul> <p>他到底会调用三还是调用一亿呢？</p> <ul><li>PPT中的问题</li></ul> <p>函数一和三可以并存吗？</p> <p>如果也可以调用到一也可以调用到三编译器就会报错说，歧义。
那到底他们能不能并存呢？
<strong>答案是可以定存。表示没有歧义</strong>。
那我们用人的眼睛来看看。
他可以接受任意一个数个数，所以这里四个放进来，ok 呀。
他呢他接受一个还一堆，所以说四个放进了也ok。</p> <p>按理说这是indigence 歧义。</p> <ul><li><font style="background:yellow;"><strong>不过模板就所谓的特化这个概念，谁更特化，谁更特别，就要用谁</strong>。 </font></li></ul> <p>好像你可能想说这个我我我从人类的逻辑上，我分不出谁比较特别。或者你认为左边这个比较特别。</p> <ul><li>那<strong>至少在计算机在，在现在草堂的技术里面认为：函数1是比较特别的</strong>。</li> <li>四个比较特别，还是一家三个比较特别比较特化？认为一加三更特别一些。
所以当这里的。</li> <li>左边版本跟右边把并存的时候
<ul><li>答案是一比较特化。左边这个比较特。
所以他们两个可以共同存在。</li> <li>那他们共同存在的话呢，这个三就永远不会被调动起来了。永远不会。</li> <li>即使你这个recursive 递归啊，最后剩下一个元素好了。最后剩下一个人数要调用的时候。
<ul><li>那这边是1加0个。这边是一个。啊，都符合条件，但他还是会非常比较特化的那一个版本。</li> <li>那最后变成0个呢。0个就跑到这里来了，跟他们两都无关。所以这里的一二三全部写出来。
可以编译通过，但是3永远不会被调用。</li> <li>他的角色就被一左边这个一这个版本取代。</li> <li><font style="background:yellow;">这是我的第一个例子。</font></li></ul></li></ul></li></ul> <h2 id="_16-variadic-templates-2"><a href="#_16-variadic-templates-2" class="header-anchor">#</a> 16. Variadic Templates 2</h2> <ul><li>第2个例子是用这个去重写<code>printf</code></li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172118057.png" alt="image-20210726172118057"></p> <p>我曾经在标准C++标准库里面的最后一部分这个课程啊跟大家谈过cout的是一个什么样的东西。
呃，他有没有他有没有写，或者你丢出去的东西，你有没有对这个操作服做重返？
这个有一些条件，但在这一个时间上不管了，反正就要往吃要丢。
万一丢不出去，编译器到这里会停下来出错报错。那我们再来看这个bring the f 本身的设计，这样是没有错的。
这个概念也是很对呀，东西能不能往c 一样的丢失你这个东西的事情跟我print有什么关系呢？我print 的任务就是这样一个一个的抓出来丢。</p> <p>石头能不能丢给吃药的那要看石头怎么洗，石头有没有去做这个操作服的重返。
所以这样的一个逻辑是正确的。</p> <p>他为了模拟这些事情，继续要找到的话，我就抛出异常。
这是借用这个wrong time error 这个异常。</p> <p>这个异常呢是也是一个比较大的题目。我会另外有一个门课程来探讨呃。有标准库提供的一些标准的异常，让你来使用。我们这个地方叫借用run time error 放了一个字符串进去。</p> <p>好，这个就是这主要的运行方式。</p> <p>我们借用Variadic Templates以前我们可能感觉很难写的这个很特殊的这个print f 呢。</p> <p>现在这么简单就实现出来。</p> <ul><li>这是我准备的第二个例子。</li></ul> <h2 id="⏳17-variadic-templates-3"><a href="#⏳17-variadic-templates-3" class="header-anchor">#</a> ⏳17. Variadic Templates 3</h2> <p>接下来是第三个例子。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172155769.png" alt="image-20210726172155769"></p> <p>我想设计一个函数叫max mara ma x next x man。
能够去判断，能够去检测出一堆数据里面最大的那一个。
哦。
我们可能都用过，或我们自己也写过，像max m 这样的函数。
在一家早期版本的标准库。
也有提供一个这样的函数，next x 嘛它是比较a b 两个东西或xy，反正两个参数的大小。
他只能比两个。
这个版本到了是一家叫二点零，仍然存在。
啊，二点零还给你一个另外一个max m 函数的版本，它可以接收任意参数。
其实要接受任意参数，不一定要用现在谈这个技术主题叫very addict template 来实现。
不一定。
如果你要比的大小是同一种类型的话，你根本不必用very edc template 来实现。
你只要用initialize the list 就好了。
现在我来就来带你看这个手法。所以这一个其实不是very edc template，不是。
但他也是在处理个数不限的一种状态。所以我把这拿来放到第三来来提醒你。
提醒你什么事情呢？
参数个数不限，但是他的类型都一样的话，用这种技巧。
不需要用到。
very attic template.
现在你看到的这些代码从哪儿来的呢？每一块都有一个，前面我有一个注记，这都是从标准库。
里头拿到的。
呃，是不是说同一个文件呢？
两个文件啊，你仔细看，他来自两个文件。
好，我打算这么去调用。
呃，我在说明一点，我已经把这些东西全部抓出来。
放到测试程序里头去了。
说我已经不是在用标准库的那一个，我在用现在这一二三四四块代码所形成的一个东西。
我要调用max 放这些元素进去。
这个地方。
我在第二的时候放大挂号。
这一次看到大括号就会自动形成一个initialize list。这个在前面提过。
这也是in should like the least。c 加加二点零新东西。
形成了一个这样的东西。那这个东西当时我们在提的时候，就在第一讲的前面提过，当时在提的时候还说他的背后是一个array。
c 加加的一个新容器的array。
背后的知识他。
所以你就可以想象这一二三四五六六个整数倍放到一个arrange 头。
这里头进来之后。
调用下一个函数在。
makes my elements 在这里。
这里设定的是要把这一个initialize list。
头尾指针其实就是那个尔瑞的指责。
背后是个位嘛啊，而为了头围两根指针的，或者叫迭代器广泛的价价，别担心。
传到这个函数了。
它具有头尾了范围啦。
接下来他在调用这个函数。
我这边线条都帮你拉好了这一个函数。
哦，这条线条拉错了，这里跑到这里来，这里面调用这个函数，这个函数这条线条应该从这里开始啊，就注意这一点。
就这一条线条要从这里开始。
好，他这是上面这个函数。
但是他在调用之前。
这里给的参数要注意，所以现在已经有头围两根指针了，但是怎么比大小呢？
靠这个条件。
这个是什么？这是一个太浅蓝色，这是一个太太不后面加小挂号就形成一个。
形成一个临时对象。
我将这一段讲的是对的，但是这其实是一个type 吗？
不是。
我这边看。
他并不是一个太。
它是一个方式，所以回到这里来，这是调用一个函数。
那想必是要说到他的返回值了，return value 返回值了啊，看看他。
这一个函数要return 什么东西？每天紫色的这个。
紫色的这个那就真的是一个tape 了，在下面这里，所以这是一个差等产生临时对象。
我在设定这些颜色的时候啊。
大致上啊可能百分之九十或者九十五张投影片。我在。
class 的名称或者是。
structure 的名称，我们尽量用这种颜色方式呢，我用是蓝色调用方式，我用潜能。
这个。
当然每一章也可能每一张投影片也可能因为局部的关系会有点变化。但我大致上是这么设计。
所以我会比较方便，我看的时候反应比较快。
好，回到这里，所以呀这边要调用下去的时候，这边就放进了这个怎么样比大小。
怎么样比大小这个东西一个一定是一个仿函数或者是这个函数物对象怎么获得的呢？借由调用这个函数来获得。
那这个函数是传回去什么给他呢？传回去这一种东西的一个临时对象。
那这种东西是什么呢？它里头有重载这个小挂号，所以他是可被调用的这一个内。
这个类所做出来的对象将可以被。
像函数一样的使用，所以将对象函数函数对象。
他怎么样比大小呢？这里的他用小鱼这个符号在比大小。
所以前头往前推，你如果曾经就是整数的话，怎么比大小用小于这个符号？
那如果你存进去是石头呢，这他也是小于。
但是石头就要有责任去。
定义。
他的小羽是什么？
在这个c 加加有操作操作符重载的这种超级功能。所以我们就可以把。
这里的逻辑汗真正怎么比大小把它分开来。
闭门造驹在这里闭门造句是好事情啊。
反正你该怎么比大小，你设计师头的人自己去处理。
好，我们把话题拉回他之所以从这个maxmara。
这里调用这个函数。
这个函数这里啊往上调用，并且就夹带了这笔大小的动作。
这个上去之后，这里就有头尾焊比大小的准则，这是一个方式。
里头怎么办呢？就用why 一个一个走。
你就把一堆元素里面两个元素比大小之后，拿第三个再拿第四个，再拿第五个来比。
就是这个弯路。
这样就完成了这个例子说的next x 马可接受任意参数个数。
这是我们的第三个例子。
那你肯定会想。
这个接口不太是我所预期的。
我本来预期的是有一个max 吗？
我可以从任意的整数，不只是专利的石头或者是任意的什么东西进去，我不要加上这个大褂号。
加上大括号是为了配合这个函数的设计，是initialize list。那你一定要给他一个这种东西就。
用大括号来形成这种东西。
所以如果不要大挂号的话。
那mix 嘛就要有不一样的设计。
就不能借用这个东西了。
这就是我下一个例子。第四，我们要探讨。
另外一个做法。</p> <h2 id="⏳18-variadic-templates-4"><a href="#⏳18-variadic-templates-4" class="header-anchor">#</a> ⏳18. Variadic Templates 4</h2> <p>第四个例子，延续刚刚的话题。</p> <p>更简单。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172308799.png" alt="image-20210726172308799"></p> <p>接口呢也可能更符合大家的预想。
在你现在所看到代码里头。
这个函数换了一个名字叫做max 吗？
先前是m a x 现在把全名maximum 写出来。
呃，其实我在。
进行测试的时候，我都让每一个单元。
在我自己的一个在一个独特的命名空间里头。
你各位你会拿到我整个测试程序，你会看到很多很多的name space 命名空间。啊，我可能叫j j 零e g j 零二j j 零。
班这样子。
这样子因此各不干扰，像我要独立一块出来方便，我也不想写二十个测试程序，三十个测试程序五十个，每一个都在测试一件事情。
这我也不想这样。
所以我用这种各自的命名空间呢就非常的独特。我甚至于每一个命名空间之前，我就有自己的include。
寒入一些头文件，因此在同一个测试文件里头，点c pp 里头。
可能同一个。
投文件被include 好多次。
因为不同的单元可能都需要它，但是我还是把它写出来。但是这个悲寒入一次以上人并没有关系，他里头有自己的一个保护作用。
在头文件里头，他有他指挥。悲寒入一。
好，回到这里。所以如果你还是使用mix 吗？m a x 跟上一页一样，那一个函数名称其实是ok 的。
在你自己的命名空间里头，也不会跟。
跟。
看这个。
和这个标准库呢，铜陵而。
冲突不会。
好，现在回到这里。
既然我手上已经有标准库的那一个。
函数是这一个。
s t t 冒号绑这一个。
他是接受两个参数。
那我何不利用他呢？
我这样一二三四五六六个参数不是可以分解成。
一加五嘛。
或者分解成二加。
我就利用这样的分解。
然后一次一次的调用标准库的这一个。
就解决了。
这个例子就是这么做的。
好。
啊，首先他的接口就没有那个大括号了，也许你觉得那个大括号很碍眼，就是上一个版本是这样的，现在回复到你想要的状态。
调用它。
这里。
这这个线条要调整一下这个地方，这是只接受一个参数。
这里我有六个参数啊，这个条这条线呢我画的太匆忙了，应该要拉到来往下面这一个。
你拿到的投影骗人。
肯定是我改过之后才会给你，现在是这样啊，请你注意这条线到到这里来。
好，这样到下面这里，这里会分成一加后面那一包。
于是这里头。
就把一。
汉后面那一包。
调用这个标准库的这一个想要去去去比较大小。
而这一个函数就会掉谁？
他一再一次这样自己他又分解。
所以在第一次调用的时候是第二个是标准库c 一个是一汗，后面这一包这时候没有办法被直接得到结果。
没有办法。
所以这里头的东西。
又要再一次调用进去，又分解成一看后面那一包，一直这边有一个stack 的一个一个作用啊。
是调用进去都还没有能够觉得到结果，一直调用到最后呢是。
标准函数的一个焊一个。
如果一个还是零个呢，那林哥会跑到上面来。
嗯，他这一指标下去最后的那一个那一个再一次调用是一个很零个。
一三零的这个零会变成这里的二跑到这一个版本跑过来。
所以一次一次调用下去。
好，对不起，我讲说医案零啊，不是这个这个零呢，当最后这一包变成一亿的时候，就跑到这里来了。
所以最后的一个情况。
是。
这边一个函数，而一个参数跟这么一个陈述。那这时候标准库的max 榜就起作用了。
好，怎么是这样说哦，我这个调用它这样他这样他这样他他但是都还没有解决问题，一直到最后那一次呢，标准库的那个max。
得到结果了，然后再回来回来回来回来回来。
利用这种形式。
也可以完成这不断的调用来得到最大值的获取。
这个是。
例子四的一个写法。
我这篇文字是说其实标准库的max m 我们现在电脑是这一个吗？
我说max one 一可接受任意个数的参数。
我其实指的是上一届的这一个。
这个在用的时候要加上大括号。
这是我们的第四个例子。</p> <h2 id="⏳19-variadic-templates-5"><a href="#⏳19-variadic-templates-5" class="header-anchor">#</a> ⏳19. Variadic Templates 5</h2> <p>接下来我们来看第五个例子，这个例子比较复杂一些，大家心里。
对，代码其实也不多。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172344447.png" alt="image-20210726172344447"></p> <p>这一次我们用的是。
类模板。
上去。
小。
借由产生这个类模板的对象啊。
然后把自己的地头的模板参数了一个一个的分解开来。
在这个之前我们写的都是函数模板，现在用的是类模板，是第一个不一样。
那这里为什么要这样子用？
这一个例子有一个很大跟前面的问题不一样的地方，就是我们要以易于一般的。
方式来处理第一个元素和最后一个月。
如果碰到这种情况。
你本来一个一个元素拿出来了，你都用一样的方式去对待他，去处理它。比如说你要打印还是你要怎么样。
你把它乘以二加三除以五等等等这个。
都是一样的操作方式，你就可以用前面的做法。
首尾不同的话，你可以参考这个做。
在这个例子里头，我想要这是我的一个用法。
我想要打印出这一串东西。
可是我的打印的形式是。
头捍卫加上这个中国哈。
这看起来更漂亮。
而且中间的这每一个元素。
打完反应完之后做一个逗点。
但是最后一个元素没有动点。
啊，如果他有逗点，那看起来就很奇怪了。
所以我想要得到这种结果，可见对于头跟尾的操作方式要特别的不同。
其他的操作方式呢相同，其他元素的操作方式相同。
这怎么办呢？
想必在这个发展过程里头，我必须知道到底真正的元素有几个。
所以我需要用到five of 点点点。
前面已经介绍过这个东西了。
我就知道有几个之后我还要知道现在在操作第几个。
这样我就能够知道我现在处理的是否或者是不是无味。
还是是中间的那一些。
这是第一个关键点。我要使用三种点点。
好，我们可以开始下去了。
我想要做这个动作。
这个是什么？
这里是做出一个tup 把它丢给吃药。
q p 我们是标准库的一部分。
我在第二讲里面会去谈秋波。
不过。
在下一个例子第六个例子里头。
当我在展现这个技巧的时候，其实我就是拿就不坐立。
所以第六第六个例子看完之后，其实你对酒保的百分之九十的原理。
完全都可以掌握了。
好，那现在讲说我现在告诉你super 是什么呢？就是可以任意的元素组合成一个团体，主要在一团灼成一包。
我现在就把这些东西组合起来。
组合起来之后，我要丢给cout，我希望是要的把它解析开来，打印成这样子。
所以首先我必须写一个操作们重返。
他接受的第一参数是。
向cout 的那种东西，呃，就是这种。
第二参数呢，大家看这个地方啊是右右边这个是什么？是一个突破，就是这里的第二层出。
所以类型这个窘况。
里头有几个元素呢？未定。
就随便我指定几个这边通吃。
进来之后，由于我需要左右两个中瓜哈，所以我这边先打印出。
这个符号。
然后我去一个一个的解析。
解析完毕之后，就把这些东西全部打印出来了。
我在打印出右边这个种瓜哈。
这样就是完成了这个我的目的是这样。
好，里头这边呢？
由于想要知道现在的处理第几个参数。
所以。
放了一个音在紫进去。
一开始是零吗？
可以想象这个index 在这个递归调用，这现在不能讲掉，用现在应该想创建递归的一代一代的创建的过程里头这个。
零要变成一一变成二，变成三。
你可以看到这里有加一的动作。
所以这边创建了这种东西之后，这个里头又在创建，就递归的。要不就走这一条路，要不就走。
条路。
不管是走这一条或者走这一条。
走到这一条，就是边检的最后的动作了。那他不断的在调用这个过程里头呢，这个一直在家里，所以这个理应然后进去一二三。
借由这种方式来知道现在。
在处理第几个参数？
也就是第几次的递归。
后面还有一个参数，这是什么size of？
点点点。
这是。
这是什么？这是这一堆东西这一堆是什么呢？
就是这个。
所以我们可以知道。
这个塞子以这个例子来看，一二三四道的是。
这个似传进来，就是这里的max。
这个maxx 马在整个运作过程中是不会变。
那我们就掌握到精髓了。
哦。
我抓出了有总共有四个参数，并且这个index 不断的累加，一开始是零。
所以我就靠靠着这两个东西。
就能够知道我是不是在处理最初的那个元素，还是在处理最后的元素，还是在处理中间的元素。
好，所谓叫。
所以在头尾特别的话，就要用这种技巧。
那第三个参数是什么？就是那一堆东西就把它直接pass 过了，你传递过来。
好，这边开始做递归，现在不是函数调用，其实里头有函数，真正的函数。the print 这个bring。
但是他是在这里头的，所以其实不断的干什么，不断的创建对象或创建对象。
创建完之后马上调用复印件。
你可能需要这个看起来有点可怕的一些。
一些动作你可能要听歌呢。
思考一下。
我们来看看它的递归动作。
如果他这边网上要用他自己。
由于这一个。
in idx 有加一。
所以一开始是零进去以后加一就变成一，然后二然后三。
每一次加完之后都拿来比，看他跟next 嘛是不是相等，就知道是不是把它全部处理完毕。
在进行这一个比较动作之前。
蓝底的这一块。
先取出突破的参数。
这个是因为这个例子是用q 专门在处理。邱鹏，你看这个。
丢给cout 是youtube 啊，专门在处理他的，所以。
这边要么是救火的专用函数。
这其实也不是函数了，他是用函数来表达哈，比较让大家快速接受。
所以这样就是去取出一零个或者下一次的第一个或者第二个或者第三个。秋风。
super 有提供这么一种接口，可以让你去取。
取出来之后。
丢给cout。
那就打印出这个符号呢。
或者后面这个好肉，或者后面这个邪了。
打印。
来之后。
要不要打印出这个逗点呢？
那就看看是不是。
处理的是最后一个元素。
如果是。
就做这个动作，什么西药的丢给吃药的，有这个东西。
这是一个空的字符。
呃，如果是最后一个就空字符，也就是不打印。如果不是，那就反映出豆点。
这不就是结果吗？
如果是最后一个，那就不打印东西了。
要不然的话，其他都是会打印出一个逗点。
这就是这一行的。
就这样的一再一再递归的创建。
创建马上调用函数啊，一再一再的进行一直进行到设备已经是一个边界条件。
这个边界条件是什么？
他的模板参数只有点。
前面都是三个。
一二三，这是两个。
那表示什么情况呢？
我们来看看。
如果最后已经是相等了。
那这边应该有一个跑过来的结果啊。
这边。
哦，ok.
还是三个参数？
只不过由于这前两个参数的摊类型一样，所以在模板参数这边你看到是只有。
合而为一的一个模板。
其实传进来的还是三个。
那这三个前两个相等。
一就表示说你现在在处理的dn 的元素汉总共有多少个元素？那个n 是相同的。
max mara max 那就表示终于处理完毕了。
所以低头。
这个动作就什么都不做，已经啊最后这一个处理完成了。
这边全部结束之后。
最后会当初是从这里调用，所以一直在这边跑。
最后还会回到这里来，再把右边这个中括号打印出来。
这样就结束了。
所以我们在这个例子里头看到一个崭新的做法啊，可以来处理头尾。
的元素呢可以有特别不一样的处理方式，就采用这种。
这是我们的第五个例子。</p> <h2 id="⏳20-variadic-templates-6-1"><a href="#⏳20-variadic-templates-6-1" class="header-anchor">#</a> ⏳20. Variadic Templates 6(1)</h2> <p>嗯嗯好，我们进行第六个例子。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172424497.png" alt="image-20210726172424497"></p> <p>very。
at，time。
please。
第六个例子，前面所谈到的都是递归，递归借由参数分解来进行递归，要不就是依规的调用你面对的你大概实现出一个函数模板，所以你用调用递归的调用或者像刚刚的第这现在是第六。
第五个例子呢是递归的创建设计是一个内模板，内模板要靠创建，不能讲调用帝国的创建，创建完之后再调用函数。
那现在这个第六个例子呢是递归的继承，哇这个就非常的特别。
我所展现出来的这个代码就是top。
top是二点零的标准库提供的一个类。
其实在g l one前面介绍过有个版本，二零零三年叫tier one，他跟那个report one就已经出现了。
▁q博是一个很不错的东西，但是当时的做法很嗯studied这个愚蠢，就是用非常直观的、暴力的方式，现在也不去谈他了啊。
等我到第二讲标准库的时候，top的实作在这里就讲完了，到时候我们就会很轻松，到时候我就会给一张投影片，让大家看一看当初t，r，one，student这些做法什么叫做暴力式的、直观式的做法。
那现在不去提他。
这个就是正规军做法，也就是二点零之后的做法，用的是什么呢？
就是递归继承继承要继承什么？
继承一个类，一个克拉斯，一个T类型，所以一定要采用魔类模板。
左手边直走，而不能是前面的一些例子是函数模板，不行。
这个做法是这样，首先看用法，QQ，因为我们还没有正式的玩这个全面性的介绍。
top。
但是在前面的例子里面呢，再看一眼，已经用过已经用过秋波了，这里就是MC to B，你可以把任意的东西。
组合这一包。
这里mac to pro是一个方便的函数，其实我们真正要建立他的类型的话，应该是突破尖挂号这个这个这个一些四个类型，用建国号的形式，然后再创建一个修补对象。
好，就到这里了。
呃那么top被创建出来的时候，被设定好，它的模板参数一进来马上被分解成一个焊一包。
如果只有一个的话，那当然就是一个加零个，这一包就是零。
所以无论如何那除非是零，零个，一开始就是零个，那编译器一定是报错的。
这个也没有人会这样用，所以这样的设计接口是对的。
一加n个之后一进来呢，最关键的地方就是首先把这个一一个拿来声明一个变量。
其他的那一一堆呢拿来当成再创建出一个top，并且继承下来。
关键就在这里，一和n，这个一拿来声明一个变量，这个n呢？
n再次做一次修补，继承下去，于是又跑到这里来，又跑到这一个类来，但是这时候参数变少一点，继续下去。
就形成了这个图。
比如说现在我要做一个top，是这样这样这样的组合，做出一个对象，绿色的低，这样这样这样的组合，根据刚刚的分析，一进去这个I，N，T这里。
建立了一个成员数据，它的值是多少呢？
四十一。
这个怎么射进去的？
现在还没看，我们刚刚只是把最关键的抓出来，四十一次进去。
那他继承了谁呢？
它继承的是后面那两个。
呃就这样，它又形成一个求佛，也就是画在这里。
他就继承上学了这两个又拿出其中的一个，再声明一个变量，然后再往上继承，那就剩一个了。
这一个又把这个第一个拿来声明一个变量，再往上继承，就是空了，空就跑到这里了，什么都没有，一个空的泪，他没有data这样的一个继承东西。
而建立起来的对象是这个东西。
我们现在从内存的角度也来考验一下大家对内存对象占用内存你有多少理解？
看这个图。
继承关系。
内存角度呢我们可以这样讲。
子类的对象，它的里头我所谓里头就是内存子类的对象里头有一个父类的成分，一个pp，一个成分在里面画成图就是这样子。
这个对这个这个对象的数据放在这里，他往上继承，所以占用了上面这一块，它的父类在这个地方，所以他有一个foot放在这里，他又往上继承上面这个呢这个string，string其实是一个指针，放在这里。
更往上呢空，那我就不画了，空不占内存嘛。
所以当这个代码写这样子去创建这个突破的时候，这个小绿色的小T。
A，这个内存是多少呢？
就是这些加起来就是这一块。
就是这个小弟。
太棒了。
我们可以利用这一种递归继承的形式，去任意地写出到底要把哪几个类型组合成一包，并且给它的纸。
由于左手边这个递归继承得到右边这个图，由于右边这个图得到内存里面的长相。
是这样，这完全就是我们所要的东西。
正正式把整数、浮点数跟字符串放进整数、浮点数、字符串、方程包靠的就是异鬼继承。
非常巧妙的一个做法。
剩下的只是细节，我们看一看有哪些细节。
首先它继承呢用的是private，这个非常好，他们之间不能说谁是一种，谁说不过去，所以用继承子孙，private继承只是为了得到内存的这个这个继承体系。
还有什么呢？
这个头等那一个，这个我想没有问题了。
呃类型也有了，我们生命的一个变量。
那尾部呃有有尾部吗？
这里没有尾部。
尾部已经拿来被继承啊。
其他还有什么？
这里有个差别。
啊就把尾部所造成的这个top呢换了一个名称叫in energy。
呃方便后面写代码。
这个深蓝色的就出现在这边啊，你很方便，很容易看到啊。
比如说这个这个是尾部所形成的那一包。
这里有两个函数非常重要，一个是头，一个是尾尾部。
这个函数就是应该传回自己，并且转型为这个我现在所念的就是这样的意思。
先看头部。
好了，尾部等一下再看一次。
这个函数是要成为第一元素。
pad，第一元素。
第一元素传回来。
那就是这个咯。
可是从她的嘴唇菜谱要怎么写呢？
稍微有点头痛，但也不太头痛。
这个就传回这个东西的态度。
那他是什么菜谱呢？
哦这一个这个type去问你的type是什么，这样就是答案。
那这一个语法为了让编译器认识，只要你看到这个冒号冒号你就要前面讲产品链。
这有些编编译器不是那么的严谨啊。
他可能你没有写他们，那他也你也他也通过了，不过正规应该要写。
这个是头那、尾巴那些呢？
我们看这个图，如果调用黑的这个函数，就取出这一个了。
那调用health应该取出，剩下的这一这块怎么拿到？
这边有个技巧啊，历史就自己历史现在应该指向这里了啊。
这一个指针转型为粗的灰，微编的这一个本来它是指向整个三格，现在转为灰边，这个就指向两这个就是尾巴嘛。
所以k有这个函数就把自己传回来这个东西这样，这个转型动作转为什么？
尾巴那种那一包奶包是什么类型？
就是这种类型。
这就是这样，我们靠着这两个函数就可以一一一直一站一站地把这个元素拿出来。
比如这样，你现在得到一个对象了，要用黑的就能得到四十亿，要用ko，得到的是什么呢？
得到的是一个指针，指向这个位置，其实我应该拉到这里来，就像这个位置如果都从左上角画起的话，我的意思一样。
那如果是调用tail里面的head呢？
这个现在就是tail里面的黑的，那就是这一个了。
就达到六点三。
可以这样一再一再的去调用配偶的配偶的配偶里面的head，这样就可以一再一再的去。
对这个递归上头的东西。
啊秋跑真正的突破。
现在你看到这是一个这个可以运作，这是编译过了这个简易版的QQ，所以他没有设计出一些很方便的函数。
如果你真的在这种情况之下，现在这个阳春版本呢你要一个一个去拿元素的话，你就得调用好几次的kill，一直在用一直调用，然后才拿到一个。
这这个层次如果很深的话，你就要讲好听。
不过有了这一个功能，我们都可以联想，已经毫无问题了，你可以拿任意一个成分来拿出来都没有问题，就靠这两个函数。
还剩下什么？
还剩下怎么是？
初值这个使用的时候是这三个是它的初值是怎么塞进去的，那么想必也要看它的构造函数喽。
这边有一条线，帮你拿好了，这是它的构造函数。
在目前这个版本在目前这个这是一个递归嘛。
那这个递归的现在所看到的这个情况呢是一个汉恩格这一个就设定到唯一的这个数据成分里头成员里头。
那另外的恩格呢另外的恩格就说道剩下的那一堆里头。
这个语法要小心。
看起来好像这是一个太这是一个菜，加上小括号，那不就是要产生创建临时对象吗？
它的那个叫小括号给出值。
但是这里说不要误以为是这样啊，那刚刚没有的认识其实是对的，可是这一行是这么独特的，它是位置在这里，这是一个初值设定，international的。
所以这个地方要解释，不能解释为创建临时对象。
它其实是调用父类，这里不是prime的这个吗？
这个就是这个它其实是调用父类。
构造数。
所以这个to top等于在构造函数的时候做的事情，是把第一个成分定好、设好，把其他的呢要用父类的构造函数让他去处理吧。
因此一再一再地往上调用，就可以逐一的把每次拿出一个成分出来，这里出值，每次拿出一个来设定。
这就是射粗子的方式非常的精简，漂亮的一个做法。
c加加标准库的top，就是这么做出来。
我第一次看到这个东西的时候，真是拍案叫绝。
巧妙。
我在准备这一次这一张投影片的时候，我拿我手上的有四点五版的、四点八版、四点九版的跟五C的标准库拿出来都跟这个长得不太一样，复杂很多。
我就在想，那这一块当初我是从哪里获得的呢？
这当然不是我凭空想象的，我从哪里获得的，但是获得之后是被我改装过呢还是怎么样？
这个来源我已经忘记了，只是后来新的版本涨的都不是这样。
所以我就想，那我一定要测试一下，我跟课程里面给各位讲的所有的东西，我都是经过测试。
我测试的结果，掏出一颗炸弹出来。
测试，不过错误出在哪里？
这个地方这上海是七啊。
好，我要表现的是下面这个定义，报错在这个位置上，吓出一身冷汗。
本来这个逻辑整个都是对的，拍案叫绝，争议。
不过那我怎么样对你交代呢？
我必须把这个改改掉，我们就来分析啊我们一起来分析这个地方哪里出，我们要把这个报错信息给你啊不过那个也很艰涩，我们凭我们的技术来看看。
该怎么去改它？
以现实情况来讲，这三个参数、这三个类型一一的进来，所以第一个黑的这个紫色的这个黑的这是一个title嘛，在上面这是一个态度，就是这里的I、M、T。
所以这里要问阿恩提问说你的态度是什么？
怎么可能问出来呢？
I、N、T，哪里能回答这种问题？
后面第二个是foot也回答不了啊，第三个是sing。
sing倒是不知道啊，虽然是个class，他也没有能够回答。
这个泰迪饭不知道，所以问题就出在这里。
那么怎么样让这个能够通过呢？
我就想。
好，前面我们学到一个关键字叫做decream，time，the，clear，time。
不太久以前你可以往上去寻一下，你可能还不允许，你还有个小括号，好像函数调用一样，允许你把任何的类型、任何的东西、任何的expression表达式放进去。
说请你丁一七帮我告诉我他的态度是什么。
我想也许那是一个工具。
那现在在这种情况这里呢，我这一个我可以问兵这个态度是什么？
所以。
看下一页下一页跟三一差别在哪里？
这边都是次要的，我刚刚已经全部分析过了，这边全部拿掉，只留下这一个地方，然后改掉，改掉哪里呢？
改掉。
这个位置有点偏差，等一下我会解释。
这一行黄色的这一行，这个黑的这个函数嘛，刚刚在上一页是这里这个A的这个函数。
rt这个东西好，回到这边来，rt这个东西没变。
所以我现在就想那这样好了，我利用比克那些菜编译器，请你帮我找出来这个的菜谱是什么。
这一行写法就是我们前面在介绍这个东西的时候说。
它就是一个table of，我们非常盼望的有一个type of来帮助我们。
这个可以。
好，这样就得到一个菜谱啦。
那这个type呢回到上一页，我应该写在这个位置上。
呃这个是黑的嘛，它的返回类型这一块，当初就是这里出错，我应该把它写到这里来，可是写到这里的时候我们又遇到一个问题，编译器在编的时候看到你你和那个太本挂号里面是这个东西，可是编到这里的时候这个还没出现这个问题。
他那个浪打是一样的，所以我们就借用那么大的那一种鱼。
这个函数的ret。
type就不写在左手边呢，就用箭头符号写在右手边，现在又省电。
哎这样子，并且呢那这一个这一整行这个黑的在哪儿？
它在下头，回到三个月了，他在下头。
我们一般这个每个人的习惯不一样啊，在标准库里面大部分都把数据放在类的最像。
嗯所以写成这样之后呢，这个东西在下头还没出现。
哎呀这个太麻烦了。
那把它移到上头来好了，所以我现在移到上面，让编译器在编译的过程里面先看到它，然后继续编译下去就。
对，通过这个知道他的菜谱是什么。
啊这样做完成。
太好了，编译通过测试，看看这个测试跟上一页是完全一样的。
上一页的这个地方。
好，我想把这样通过了啊放进来的这四个珠子都打印出来，打印的结果是这个。
没错，这是我要的。
打印的方式呢抓住孩子，然后抓住尾巴的黑的，再夹住尾巴的尾巴的黑，如果还有的话，就尾巴的尾巴的尾巴的尾巴的黑，就这样一个一个调用。
当然你就可以在这个基础上再写出一些比较好的函数的，直接调用第三个拿第三个黑的，或者拿。
第五个态度太好了。
顺便也把前面学过的一些c加加二点零的语言上的东西呢拿来实证一番。
就过了一个小时之后，我来想我是不是太复杂了？
大题小做啊。
当然一方面也得到了技术上的收获，但是我们回到前面这个爆炸点，在这里。
当初就编译器编到这里是通不过。
所以这一个函数的retain要retain什么态度呢？
是这个东西的态类型这里是用问的，这不是多。
此一举吗？
这一行不就说了这个东西的type就是他为什么还要去问他呢？
直接就把它写在这里就好了嘛。
我突然有这样的想法。
所以刚刚进行到这个改成这样之后是OK的，我再把它改成这样也OK啊。
所以刚刚我们想的太复杂我想的太复杂了。
现在这个那我们有三个版本啊，一开始是没有通过编译有炸弹的那个版本，那后来在上一页呢我做了一个小改变，这一页呢又改回来，只差别在于跟第一版本的，这是第三。
慢的第一版本的差别只在于差别在哪里呢？
这个地方他不再问了，直接就拿这个黑的来用。
愿意成功，理应如此。
所以这样就太好了，当初再回到前面来。
第一版本，这是第三，这是第二。
这是第一第一版本这一块，我刚刚说我自己也行，想起来会晓得，这一块当初从哪儿来的，我都我知道了。
这是我们的第六个例子，非常巧妙地用递归继承。</p> <h2 id="⏳21-variadic-templates-7-c-keywords"><a href="#⏳21-variadic-templates-7-c-keywords" class="header-anchor">#</a> ⏳21. Variadic Templates_7 &amp; C++ Keywords</h2> <p>我们再来看第七个例子，我一共对于这个very artic。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172543367.png" alt="image-20210726172543367"></p> <p>increase, 我准备了七个例子，就是最后一个例子。
前面第六个例子，我们看到就是从邱破的这个源代码里头去学习到原来递归可以递归的继承。
于是我就在想，那么可不可以递归的复合呢？
composition 复合相对于inheritance 继承。
可不可以递归的复合呢？就是我里头内涵的一个。
比如说我就跑的设计是。
里头有有五个成分。
啊，那么呃化身图直接看图好了，我把它是这样子。
这个停泊是设计以三个类型组成的。
在这里头，我让他内含一个两个所组成的两个里面内含一个这个组成，这是那样一个这个。
这样是不是也可以实现，那感觉是好像可以，我就开始着手进行。
于是我设计这个东西。
我不知道标准库里面有没有什么。
什么类什么class 是用这种技巧，不知道。
好，那我还是把这个class 呢叫tup。
如果我是单独包在每一个name space 命名空间，我测试的时候，每一个命名空间其实这里还是完整的，叫tup 也可以。
不过当时我并没有把它分开来，我在同一个命名空间里头，所以我就换了一个名字叫就不好了就。
这里这个关键在哪边？
这个tube 这个class。
这里面一进来也是分为医很多。
用法是这样，用法完全跟秋婆的用法完全一样。所以这个像这样的用法，比如下面这个这个比较复杂，就看下面这个好了。
一二三四四个菜一进来就变成一加三。
这个一加三呢？
他不是一血，是什么意思？叫内涵嘛？
在这个class 里头，我就准备了两个变量，一个叫头，一个叫韦。
洪放的就是这里的紫色的尾呢，玮放的就是后面这一包。
那后面这一包。
要再创接着在递归的创建一个自己呀。
这个写法有点讨厌，所以换了一个名字叫恐怕zit。
这个手法也是摩尼。
上一个例子突破。
所以换那个tab name。哆哆摩尼。他只不过。
例子六是继承这里的变成看不进去。
内涵或者叫负荷，或者叫拥有。
都可以。
好，这是最关键的部分。
剩下什么一个就是说充值。
另外一个就是两个重要的函数，我们先看重要的函数。
这个函数是要取得铜。
现在投在哪里？就这两个啊。
投在这里。
所以这一个函数就传回这个东西嘛。
传回来的这是什么态度呢？我现在学到乖了，刚刚在粒子六里头，我不是把它想的太复杂了吗？
有版本三个版本嘛，第一个版本通不过第二个版本，第三个版本。那么第三个版本又是很回归到很简单的状态。
所以我现在学乖了，知道他要传回的是什么态b 这里不就写清楚了。所以紫色的这。
一样的道理，完全一样的道理。尾部要重回的是什么呢？
这另外一个非常。
而这个data 是什么？钛粉不就是这种态度吗？
所以穿回来是这个。
好，但是传回来一定要是一个引用。
如果传回来不是引用的话，等于是做一份拷贝出去。
做一份拷贝出去，这个tair 将来在。
使用的时候啊。
为了要一个一个取出元素。
像下面这个例子呢，它是一站一站的这样配合退啊退啊退掉里面的。
如果你传出来的是一个copy 版本的话。
拿当然也是拿到了正确的。
可是如果你要设置呢？
你拿没有问题，他虽然是拷贝，你拿的还是原来的内容？
但是如果你要改变那个内容的话。
传出来是一个咖啡呢，会会有问题。
你改的不是原始原本的那一个。
本尊不是你改的，是分身，是替身，那这样是不行的。
这里要注意。
好，这是这两个函数。
另外就是是初几。
授出质的做法就像这样子，这里是。
创建一个对象，这个就是它出自。
所以一定要去关关心到构造函数。现在叫joep，这叫就构造函数里头进来也分为遗憾多。
就把那个一射到一多，收到多就对了。
这样子。
就形成了这样的画面。
在内存的角度去看。
就是说这一个的对象，我现在这样子表现只是类看到。
他的对象里头有一个他他的对象里头有一个他他有一个他。
所以最终。
你面对的你当初是创建的是这一种东西。
这个嘛就。
三个或者这个就四个是出现这种东西。
他的大小呢他就内涵这个内涵那个就像那就是回到这个实用面来，你所做出来的这个i t。
二。
他叫内涵的内涵的什么，一个字符串，一个复数，一个一直在他那个double。
这就是这正是我们所要的啊不同类型的东西。组合成一个tap。
创建出对象。
这个输出结果。
这里有。
深层的泰尔特尔特的调用。
我前面已经提过了，你可以在这个基础上写一些比较好用的函数，直接去抓第几个，而不需要这样一再的tail。
不过现在只是一个最简单的例子，这两个输出结果的这里非常好。
这是我们的第七个例子。
所以说整个七个例子里头呢都去释放。
递归。
有递归调用有递归创建，有递归的继承和递归的负荷。
非常的丰富，利用这个very id template 可以做很多的东西。
这个是我在第一讲。
语法的部分。
最后一个主题。
也是第一个主题，首尾相呼应啊，因为这是最重要最有价值的一部分。</p> <h3 id="_21-c-关键字"><a href="#_21-c-关键字" class="header-anchor">#</a> 21.C++关键字</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210726172643104.png" alt="image-20210726172643104"></p> <p>第一讲的最后一张投影片。
这个从网页上抓出来这个画面让大家看看c 加加。
七沃尔不是只有二点零在整个c 加加到二点零为止的七word 关键字列出来。
从c 加加二点零，也就是cz eleven 之后的关键字呢，这绿色的部分也都标识给你看。
各位可以看到哪些是我们讲的，哪些是我们没有讲有有有没有提的吗？有那个什么我没有提的部分吗？还是有一些些非常少。
我认为那个实用性已经很少人会去用到了。
我们还是以实用为最主要。
所以大家可以拿这一张来比对一下。
你前面学到的东西。
这个就是第一讲的部分，整个语言的部分在接下来要谈的第二季啊。
标准库的部分呢，我就会去找出。
我认为最重要的在二点零这。
这个这个版本开始最重要的一些类来跟大家分析。
不是只有示范他的用法，还包括他。
底部的结构我们可以看到他怎么设计。
第一讲到这个地方结束。</p> <h2 id="✅-『标准库部分』"><a href="#✅-『标准库部分』" class="header-anchor">#</a> ✅ 『标准库部分』</h2> <h2 id="_22-标准库-源代码分布"><a href="#_22-标准库-源代码分布" class="header-anchor">#</a> 22.标准库-源代码分布</h2> <ul><li>现在我们课程进入第2部分—C++2.0新特性的第2讲之标准库</li> <li>『前面是语言<strong>语法</strong>、<strong>关键字</strong>』</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711083128293.png" alt="image-20210711083128293"></p> <ul><li>建议：希望你能和我一样去看到源代码！</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711083241560.png" alt="image-20210711083241560"></p> <ul><li>如果你手上不是VC或者GNU，那么你总是能找到一个include子目录。</li> <li>呃当然了，这么多的头文件你要搭配一个『全文检索』，才会更帮助你来找到你要找到的源代码。</li></ul> <h2 id="_23-右值引用和move语义『移动语义-move-semantic』⭐️"><a href="#_23-右值引用和move语义『移动语义-move-semantic』⭐️" class="header-anchor">#</a> 23.右值引用和move语义『移动语义/move semantic』⭐️</h2> <h3 id="_23-1-big-five⭐️"><a href="#_23-1-big-five⭐️" class="header-anchor">#</a> 23.1.Big five⭐️</h3> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>在原有4个特殊成员函数（默认构造函数、复制构造函数、复制赋值运算符和析构函数）的基础上，
C++11新增了两个：移动构造函数和移动赋值运算符。这些成员函数是编译器在各种情况下自动提供的。

___来自《C++ primer》18.3.新的类功能
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><ul><li>有博客说：在C++11里，类有五个已经为你写好的特殊函数。它们是析构函数，拷贝构造函数，<strong>移动构造函数</strong>，拷贝赋值操作和<strong>移动赋值操作函数</strong>。这些就是<strong>Big-Five</strong>。在许多情况下，你可以接受编译器为五大操作提供的默认函数。但是，有时你不能这样做。</li></ul> <h3 id="_23-2-面试"><a href="#_23-2-面试" class="header-anchor">#</a> 23.2.面试</h3> <ul><li><p>博客<a href="https://codinfox.github.io/dev/2014/06/03/move-semantic-perfect-forward/" target="_blank" rel="noopener noreferrer">参考<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li> <li><p>“右值引用”的<a href="https://zh.wikipedia.org/wiki/%E5%8F%B3%E5%80%BC%E5%BC%95%E7%94%A8#%E7%A7%BB%E5%8A%A8%E8%AF%AD%E4%B9%89%E4%B8%8E%E5%BC%82%E5%B8%B8" target="_blank" rel="noopener noreferrer">维基百科<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li></ul> <blockquote><p>Rvalue references and Move Semantics，（<strong>游戏公司面试考了</strong>）</p></blockquote> <ul><li>面试问了，谈一谈，左值引用和右值引用？？</li> <li>谈一谈左值和右值『看来，4个是不同的概念，，，』</li></ul> <p>我要介绍一个<strong>非常非常重要</strong>的东西，叫做右值的引用。『右值的引用』这个关系到后面的一个叫——move搬离，的语义，而这个move语义又号称是可以对于容器的效率有大幅度的改善，而容器又是你几乎都一定会用到的。所以这个层层下来了，这非常重要。</p> <p>那么这个右值引用了，按理说它<strong>是属于语言</strong>的那一部分，我怎么把它放到标准库这边第二讲来谈呢。**没错，他是语言的部分，但是他接下去发展的呢，就都是跟标准库有关。**好，所以我放到这里来谈。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713100212700.png" alt="image-20210713100212700"></p> <p>这个<strong>右值引用</strong>又是什么意思？我们看到这里的文字说明。这是一种<strong>新的Type</strong>，新的类型————引用的类型。是从其实从2003（就是TR1）之后就引入了，但是大家都不是很熟悉他。但是在2.0这个就变得很重要了。</p> <ul><li>他可以来帮助解决一个问题，什么问题呢？就是不必要copy！！</li></ul> <p><strong>事实上，copy 的事情在我们。没有意识到的情况之下呢，常常在发生</strong>！！
比如说你把一个临时对象。啊，你从你的实验室里面抓到一个数据，这个数据呢，你要包成一个对象，一个object，然后把它insert 或者是pushback 放到你的容器里头去。你可能抓一百万个数据，就要准备一百万个这一种对象，然后放到你的元素去。你这个，一个一个的数据抓出来都是一些你会制造一些临时对象。</p> <p>临时对象要放到容器去，这就是一个copy的动作。那这个copy动作其实可能非必要啊，<strong>什么情况必要，什么情况，非必要的</strong>，我们等一下再来分析</p> <p>那这个非必要的情况之下呢，那如果有一百万次，这不是就，呃，非常浪费时间的嘛。</p> <p>而且如果你把它放到容器之后，这个容器在默默的情况之下，在你不知道的情况之下呢，他也可能在做。在做很多的copy 的动作。比如说那个vector 要成长。啊，在你没有意识的情况之下，他已经默默的搬到另外一个地方去。那可能要靠比五十万个元素，七十万个元素，很多很多的元素。所以回到这里来。</p> <ul><li>这一个语义，这一个语法语义的发展就是为了：要解决非必要的拷贝。</li></ul> <p>什么叫做非必要的拷贝呢？</p> <p>这边是有一个说明：当赋值，拷贝也是一种赋值啊！！就是把东西放到另外一个地方去，这个叫assign嘛。赋值的右手边，右手边就是来源端呢，你a =b 就是把b assign给a。
那个b 在右手边，b就是来源端，拷贝的来源端啊，当右手边是一个右值的话。</p> <p>我们现在可能还不知道什么叫右值。等一下我会分析。</p> <p>当右手边是一个右值的话呢，那么左手边的这边的接受端呢。可以去偷（steal）右手边的resources，这里的resources 就是指他里头的东西啦！！</p> <p>真正要copy的东西，可以偷！！	这个字，很形象——去偷它。而不需要，rather then 而不需要去执行一个allocation 的动作。你要把这个东西赋值或者拷贝到另外一个地方去。那个另外一个地方那边呢，<strong>可以不必做：重新分配一块内存来放</strong>。<strong>他可以去偷原来的这一边</strong>。那这个一定要发生在指针的这个事情上面！！！</p> <p>这不我们等一下会继续把它弄得非常的清楚。</p> <p><strong>所以非必要的拷贝其实就是去偷！</strong>！那怎么偷呢？</p> <ul><li>现在我们现在解释一下左值（Lvalue）跟右值差别</li></ul> <p>左值：就是变量。我们一般在代码里面声明一个变量，变量是可变的，他可以接受你赋值进去。可以是在一个赋值符号的左手边，所以叫左值，，变量就是左值。</p> <p>那右值呢？他就不能放在左边的叫做右值。</p> <p>我们先来看这个例子。</p> <p>我有a b 两个变量，所以它都是左值。</p> <p>你看，a 可以放在左手边，b 也可以放在左手边，他都是左值。左值也可以放在右边啊，这个无所谓，他是可以出现在左边的。
那右值呢：<strong>只能</strong>出现在右边</p> <ul><li>这个就是右值：红色的这个：a +b 加完之后，你不能再赋值进去！这个语法这个怎么解释？</li></ul> <p>所以这个，a +b 这样就是一个右值，我们继续往下看。当然你会想说，我在代码里面不根本就不会去写这种动作嘛。我写学习写代码的第一天我就知道我不会去写这种动作！！
那这只是一个例子啊！！右值是这个形式，但是右值也可能是其他的形式。我们继续说。如果以这个为蓝本；我换那个，我不要用整数，我用其他的东西来实验一下。用字符串。或者用复数，我最喜欢就是拿这两个来试验：标准库已经提供了和我们一起。</p> <p>复数：这一个呢，它里头只有实部和虚部，他不带指针。
字符串：这个呢这里头只有一根指针，至于这个字符串本身是放在另外一个地方，用这根指针去指着他。所以这是非常典型的两种例子。</p> <p>好，我就按照这个整数的方式，我再写一遍，我们分析一下，现在我有两个字符串。我就是要模拟这个动作。这边整数编译的时候会失败嘛！！
但是我现在这样编译过去，我磨砺他呢却成功了却成功了。竟然通过编译。</p> <p>这个就很有趣。那我就想：<strong>这不就推翻了，我们的理解了嘛，对右值的理解</strong>！！
好，那我就。既然成功，那我打印出来看看好了，看看这个赋值进去是什么结果。你可以你可以体会一下这个执行结果。
还有一种情况——这个是一个临时对象。</p> <p>好，现在我来解释，右值的除了像这样之外，另外一个是我们常常写代码会出现的。就是这种临时对象。临时对象就是一个右值！！<strong>你可以这样想象：帮助你理解，右值，他没有名称。那没有名称，你怎么赋值给他呢？？</strong>？
这样子你比较容易接受这种观念，所以这个临时对象却赋值给他，竟然也可以通过，这个太奇怪了，竟然可以对临时对象赋值！！
<strong>所以我用字符串这个class 完全推翻了对整数的认识。</strong></p> <p>那我们再看看另外一个经典的例子，复数好了。好，这里呢我有两个复数。
都有默认值了。不是默认值那么多，指定给他赋值了。然后我也是模拟整数的这个加法，在这个地方，竟然也通过了！！
这边，这两个相加，可以当左值吗？？？这个是通过的，所以这个答案是yes！！！</p> <p>可以，你的讲义就把它把它打上可以！！！</p> <p>然后也是按照刚刚的方式，既然可以，那我就打印出来看看执行结果是什么？好了，那这个执行结果已经不重要了。。。
下一行，我也一样画葫芦的，以这种方式，我写出这一行临时对象把它赋值，竟然也可以，<strong>所以这两个经典的class 呢都推翻了我们对整数的理解</strong>。</p> <p>这边有一段话可以这样解释：：<strong>c ++在夹带着，他的这个，它自己定义的这一些class，每个class都是一个type。会引来一些很隐晦的，很不太能想象的一些对于modify 一些改变内容或者是赋值动作的一些，，一些让人意想不到的。大吃一惊的情况。那就会造成对于这个定义的一个不正确性，，什么定义？？？这里出现问题。（指着左上角的左值和右值的那段英语））</strong></p> <p>也就是我们对整数的理解!</p> <p>不过在这个地方无所谓，我们还是要回到我们最基本的态度来。</p> <p>就是右值是，不可以出现在左边的。
<strong>而什么是右值呢？最常见的就是临时对象。他就是右值。</strong>
虽然呢，这里推翻了这个概念！！但是因为这两个是这2个是<strong>这个标准库的作者，他自己写出来的，它没有去非常严谨的遵循这一个概念。</strong></p> <ul><li>那我们不管他。</li></ul> <p>好，所以这一页最重要的就是2件事。</p> <p>1、临时对象就是一种右值
2、右值不可以放在左边。</p> <p>我们再往下看。那这个呢。
像这样，这是一个函数，函数返回一个整数。
下面这样，我们只要分析左边跟右边就好了，这个是一个赋值操作。x 是个变量，所以放在左边当然是ok。</p> <p>第2行，这个就不ok 了。P这个变量是没有问题。问题是：这个是什么东西？
你可能会想，那这个好像是一个对函数取地址，对函数取地址就是取出函数的那个起点。你可能会这样想，那个是对的呀，从c 以来就可以了。c 的函数名称。其实就是函数的起点。也就是函数的位置——地址。『那你加不上加不加上这个取地址符号都无所谓，这个以前就可以通过，现在为什么通不过呢？』』</p> <p>因为这个并不是你想象中的那个——这个是什么。<strong>你想象的那个是没有小括号的</strong>。那他没有小括号，那就是函数的名称也就是函数的地址。
现在是有小括号，所以<strong>这意思是这一个函数的返回的东西</strong>，return value 返回一个东西，要取地址。
<strong>但是，函数返回的东西是个右值</strong>！
你对右值再去取地址？是不可以的。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713100431134.png" alt="image-20210713100431134"></p> <p>新的新的：：：可是<strong>现在发展</strong>出一个新的语法：对右值要去取地址哦，来引用！！
好，所以：右值放在等号赋值符号的右手边，天经地义。</p> <p><strong>但是当他放在右手边的时候。c++2.0现在说希望给我们一个新的语</strong>法！！！
『『让我们能够去取他的reference！！带来什么好处呢？』』</p> <p>接下去就要谈。我们等一下再来回来看这2句话。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210713100638062.png" alt="image-20210713100638062"></p> <p>好，我们先来看这张图。
右手边这个代码就是我在前面我们的第1讲里面，当时在谈到一个主题的时候还谈到。模模板模板参数。
那一个主题。</p> <p>1、所以这样子放进去之后呢，首先<strong>要有一种语法</strong>。去通知这个函数。
说。你来偷吧，我让你偷，就这个函数在哪里？
这个是容器，这个c 就是这里存进来的that。
因为这张很复杂嘛，你要从这里看起。好，这个v 成见就是这个c。
这个c 就是现在这里的c 所以调用的就是that the insert。
that could the insert. 我花在这边。
去看看他的源代码，它的insert有两个版本。
我们熟知的是这一个。『标号为1的』</p> <p>现在，是2.0，有新的语法，并且实现出这个词作，实现是什么呢？这个版本。
<strong>什么新语法？这里出现两个这个<code>&amp;&amp;</code>特殊符号</strong>。这样的意思就是说：如果传进来的，现在有两个版本。
如果传进来是Rvalue reference.，那就是这个就会跑到这里来！
右值引用就会跑到这里来，不是的话就会跑到上面这里。</p> <p>在过去以来都只有这个吗？现在新增加这一个。
我现在就画了这条线。告诉你他就会跑到这里，为什么呢？
这一个就是右值啊。</p> <p>面对右值的时候，编译器面对临时对象。一定把它当成是一个右值引用跑到这里。
跑到这里来以后做什么事情了？
这个insert，它里头开始要把一个元素放到容器之中某一个位置。in vector 来讲，我们现在这个例子是在。放进去之后，要往往尾巴推。
这个推的过程，会一再的发生copy。
所以这个insert里头，我这边画法形象的让大家了解这个理念可能是很多很多次很多次。当然也可能一次都没有啊，如果你映射到最尾巴的话。</p> <p>好，这里头呢？被一再的既然要发生copy，**他会去调用你传进来的这个东西，他的type。**也就是他的class的constructor『『注意：』』
insert 为了要copy 会去调用拷贝构造，拷贝构造呢，这一个呢，就是这一个元素的类型。我们也要写出2个版本出来：</p> <p>1、一个是跟拷贝有关的，大家以前熟悉的东西。
2、一个是专门让你来偷的。</p> <p>所以『以前』的这1个拷贝，他是一他会做这种事情：就是他真的会去分配另外一块内存啊，假设是原本是这样的话。要做拷贝的话，除了把这个要分配一个这一个啊，那指针呢要不要拷贝过来，不要拷贝过来，要另外分配一块内存，去放去放这里拷贝过来，这个也就是指针的深拷贝。『『『原理如此，原来我先前以为全是浅拷贝的，也不是，因为真的有深拷贝？？』啊，这是过去的情况。</p> <p>现在说我有这个新版本哦，那这边调用的时候已经明白的告诉我你来偷我吧。
好，所以怎么抽呢？现在偷的对象是谁？就是，你现在放进去的这个Mystring。
Mystring这个中间有个过程啊，我就不去讲他这个事实上这个例子我们前面已经带</p> <p>呃，这个就是my string。所以这边说我现在要放一个my streng 进去，而且欢迎你来偷。好，这个我来了。</p> <ul><li>这个容器确实有一个版本是准备来偷的。</li></ul> <p>他里头就一再一再的去偷</p> <p>所以他就会跑到这里来了：
至于怎么偷呢，我们先简单谈一下概念，后面就有真正的代码，他当时copy 是这样。那偷是怎么样？只要把指针拷贝过来就好了。
不用另外分配一块，像这样分配一块新的那一组。
也不用把这个内容拷贝过来，都不必，只要把指针指过去就好。</p> <p>这样就叫做偷，谁偷谁呢？新的这个东西偷了旧的这个东西，什么叫做偷呢？我指针指过去。我指导和你们一样的东西，那我就算是借用一下：：在这里形**象的说是偷。**所以我跟你，从此就指向同一个东西了，我们共享，这件事情当然是危险！</p> <p>你同一个内容有两个指针指着他。有两个人在看同一栋房子好了。呃，另外一个人决定摧毁他，放火烧掉它。a 跟b 啊，那那a 吧把它烧掉，那bb 就没有了，什么都没有了，因为他们自己成同一个房子。所以这是危险。这是危险。呃，危险怎么办呢？所以这边有一个打叉的动作。这个指针拷贝过来之后，其实这是指针的浅拷贝了。所谓偷。<strong>所谓move搬离，就是指针的浅拷贝。</strong></p> <p><strong>这个浅拷贝完成了之后，这一根指针要打断。打断就安全了，没打断就危险</strong>！！
所以打算以后他原来这个东西就没有用了，没错！</p> <p>没错，所以整个在反推回去呢，你作为右值的人，那去使用之后，他就不能再用了，<strong>他被偷了，他不能再用，所以一定要有这个认知</strong>。你一定要认识一个事情。被move之后，被偷之后呢？原来那个东西不能再用，再用就危险。在用的时候，这个指针已经打叉了。等一下真正把这个代码写完，这个点点点，你就会看到这里。我把这个指针拿掉。</p> <p>再回来检讨一下：当初说如果我决定告诉这个说：：我是一个右值，那么我接下来就不能再使用它了！！这个黄色这个东西被用了。你要想象他被偷了，接下来不能用。在这一件，现在这个点上呢。</p> <blockquote><p>临时对象是：右值的原因！！</p></blockquote> <p><strong>右值本来自己是一个临时对象，他临时对象根本没有名称，所以接下去『根本不可能用到它』。那非常好非常好！！也正是因为这样</strong>，所以编译器看到临时对象<strong>一定</strong>把它当成右值，一定走。我刚刚走这些路，一定去偷。</p> <p>另外有一种情况是：我要insert。
我这个东西不是临时对象！！不是，所以他是左值，但是我自己很清楚，接下来我不会再用这个左值，左值就是讲成变量啊，<strong>我接下来不会再去用这个变量</strong>！！</p> <p><strong>那这种情况下，我也可以想办法让他走这一条</strong>路！！这条路是用偷的方式，那显然可以大幅节省时间了！！</p> <blockquote><p>move函数的作用！！</p></blockquote> <p>我怎么去，<strong>我明明是一个左值，我却要把自己当成右值！那要怎么办呢？？？</strong> <strong>标准库就给了你一个东西叫</strong>做这个：<code>move</code> ，你只要把你的左值，你的变量。
放到这里头去！！ <strong>就相当于</strong>拿到了他的Rvalue ref. 那就会走这条路。</p> <p>很快的很短时间整理一下这概念啊。
我作为一个<strong>动作的发起者</strong>，我要调用insert，所以我是动作的发起者。我放的是一个右值</p> <p><strong>所以在2.0之前。容器的insert只有这样一个版本，现在多了这个版本</strong>！于是通知他跑到这个版本，这个版本要怎么偷呢？？？他所谓偷，是要来处理你给他的东西呀。
那你现在这个例子，你给他的是这一种：这个在当初的发起端其实是一个my String，这个是我设计的，我就得在my 村里面。
也写出一个，专门针对的版本move的版本！！！所以当他要偷要做拷贝的时候，或者拷贝赋值，或者拷贝构造都是拷贝。他会发现哦，确实有一个可以让我偷的版本，他就跑到这里了。</p> <p><strong>所以这个是新的，这个标准库里面这一段这是新的，我们写代码要搭配它，这一段是新的</strong>。
那么整个发起的动作是临时对象，一定是右值，，万一你有一个左值，你可以用这种方式<code>move</code>，这也是新的，来引发整个，这种右值move的这种动作</p> <p>说你要有右值引用可以被偷，你现在已经知道要写两个版本了。呃，语法的这个地方，但是真正要怎么写出来呢？我们就会看到一个实际的例子。</p> <h2 id="⏳24-perfect-forwarding，完美转发"><a href="#⏳24-perfect-forwarding，完美转发" class="header-anchor">#</a> ⏳24.Perfect Forwarding，完美转发</h2> <ul><li><strong>Perfect Forwarding</strong>，完美转发</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712220219741.png" alt="image-20210712220219741"></p> <p>尤其是move 这个动作对于vector特别重要。vector的这两个版本。把他的源代码挖出来给你看。
因此好吧，这个是<strong>2.9，也就是我拿来做代表，就是C++2.0之前</strong>，只有这个版本，他接受的是Pass by reference。刚刚在上1页，就这，就这个版本。
那么第2个版本呢。</p> <p>是4.9，我呢它还代表2.0之后，涉及到2.0之后的那他就有他就有两个版本。
一个是by reference。
一个呢，是传递by Rvalue reference（右值引用）。这个两个版本。</p> <p>但是这都不是重点，我们的重点是二点零之前只有一个版本，二点零之后就可以利用这个新的语法了。右值引用的新语法，设计出两个版本出来。这一张是对刚刚我们花很多时间的这一夜的这个地方做一个补充。</p> <p>那他是一个临时对象，而他会被解释为幼稚。
引用这个传进去这个tape。传到这里来之后，这里**又调用过去，所以有点像是一个快递啊。**我把这个type 传过去，就转交到这里去，这个地方再转再去调用，也就是再把这个Type 再转交到这里来，在这个过程里面呢：：遗失了一些信息。
也就是这个Type 经过这种动作，而不是如果他是直接到某1个地方去，在那边做处理。那很好，可是现在是到这里来这里再到这里来。</p> <p>你把一个东西交给顺丰快递，总不能顺丰快递说啊，对不起啊，<strong>我交到他客户手上的时候遗漏了一些东西，这里能忍受吗</strong>？</p> <p>你不能忍受！！更何况这个遗漏的东西是一个最重要的东西。在现代所谈的这种move语义之中！！</p> <p>所以到底发生了什么事情呢？如果没有一个特殊设计的话。这个转交的动作Forward转交传递的这个动作呢是一个不完美的！！刚刚就是说遗漏了一些性质。
一些信息，不完美！！
<strong>所以我们要发展出一个完美的传递的机制。</strong></p> <p>我来看看什么是不完美，是不是完美？？？</p> <p>好，所以我们往下看。啊，刚刚进行到这呃这一页嘛，这是源代码。那么下面这个呢，只是先提一下的，我们要发展的。</p> <p>我现在，我的放进去的元素类型，除了有刚刚的，copy constructor和copy move constructor。</p> <p>记住这2个我不太知道这个move呢是因为这个新东西，我们到底要中文要翻译为什么呢？我不是很有把握我，所以我们讲原文哈。</p> <blockquote><p>学习：：：</p></blockquote> <p>『『『copy和move 这两个版本。这两个版本，不但在<strong>构造函</strong>数身上要分为两个，在<strong>赋值操作</strong>上也要分为2个，也要有新的这个！！</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712220319480.png" alt="image-20210712220319480"></p> <ul><li>完美转发</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712220349203.png" alt="image-20210712220349203"></p> <p>然后我们下去看所谓的<strong>完美的转交</strong>，完美的快递。这一页上面所谈的。
其实是已经是结果了，就是这个。当使用:标准库的这个东西<code>Forward</code>就可以达到一个完美的快递。</p> <p>→不完美的转发</p> <p>但是什么是不完美的，还不知道呢！！所以我们先看下一页。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712220432657.png" alt="image-20210712220432657"></p> <p>不完美的forwarding。我们来看看这个小例子。我写了两个函数就process
这两个函数，一个是这种版本。一个是这种版本。</p> <p>我准备一些东西，看看他会变到哪一个版本。这个我有一个左值。</p> <p>那这个呢。a 是一个左值。
但是加上move之后，标准库有一个这个东西，加上幕布之后,他变成右值了
或者说请把他的亲把我当成右值，我a 啊，请你们把我当右值吧。所以这样调用到的是右值的版本。
都非常好。</p> <p><strong>接下来再设计一个中介者叫Forward</strong></p> <p>这里呢将要调用Forward而<strong>Forward 里头再去调用process。</strong>
我们刚不是说一个快递的动作吗？他快递的观点嘛，我调用你，你再用他，这个转接的过程中。我们就想模拟这个事情。
再看一次，我这边有个Forward</p> <p>糟糕了。不完美的转交。快递完美的快递。
**再讲一次，这是明明是一个右值。**放进来之后再放上去，却变成了左值
可见这个Forward设计一定有问题！！！
这不是我们要的！！！
这边有讲！
好，那怎么去解释它呢？我这里有个解释，但是就算你。也不是很懂这个解释无所谓。<strong>总之我们其实要求的是一个完美的转交，但是这里做不到</strong>。</p> <p>那这个到底该怎么设计才好？</p> <p>已经到了一种非常让人，，啊可能会让你觉得非常枯燥无谓的 <strong>一些非常底层的语言上的探讨</strong>。所以我也不打算在这里讲啊。
啊，<strong>我只表现什么给你看。：标准库做出来的东西给你看</strong>。
他说。刚刚我们说这个是失败的！！！</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221017905.png" alt="image-20210712221017905"></p> <ul><li>局部放大</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210712221050975.png" alt="image-20210712221050975"></p> <p>那么他做成什么样子呢？在这一个头文件里头，如果你有兴趣挖出来，其实这个我已经超出来了。这里头有Forward一个，这是一个模板啊。
这服务第二个，这是一个模板。
通过这2。就可以做到完美的Forward『『『学习学习』』</p> <p>我刚刚说我们不想去细谈这里头的这些动作。这个非常的枯燥无味。
但是你在看一些代码的时候。标准库的代码。你这是你是使用者，然后你想去看看代码，你会发现。怎么他会调用move，move调用之前，又调用这个Forward，原因就是我们现在所在谈的。借着这样子的设计。才能够做到完美的转交，完美的快递。</p> <p>我们整理一下。我们<strong>最终目的是希望我设计一个类型呢</strong>。
<strong>这他声称他是可以被偷的，这样的话就可以对容器的效率有大幅度的提升</strong>。所以这是我们的目标这个。</p> <p>他是在探讨这个事情之前，我们已经认识了右值引用的语法，，以及这个标准库提供的这个东西。以及。
散落在很多标准库的其他地方的。
什么东西呢？
Forward的这种东西，这Forward和move</p> <p>所有的基础呢都铺成好了，我们可以开始来写我们这个可被偷的或者叫<strong>可被搬的move aware</strong></p> <p>move aware,<strong>有move意识</strong>的这一种元素类型，我们接下来就要来学习怎么写这种东西。</p> <h2 id="_25-写一个move-aware-class"><a href="#_25-写一个move-aware-class" class="header-anchor">#</a> 25.写一个<code>Move-aware class</code></h2> <ul><li>我们现在要设计1个class，它是带着move这种意式的，，它是可以被move，在有必要的情况之下，它可以被move</li> <li><strong>那我设计好这个class之后，我打算把它当成元素的类型</strong>！！这样它带着这种轶事，将来容器需要做copy的时候，一看你有这个意式哦，，它就会用move来取代真正的拷贝！</li></ul> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711084829605.png" alt="image-20210711084829605"></p> <ul><li><p>copy constructor和copy assignment operator它们都有自己的兄弟版本，就是它们的move版本。我们现在重点就是要学习这个怎么写。</p> <ul><li>首先。他兄弟之间要区隔开来。靠这个<code>&amp;&amp;</code>区隔。这个就是右值引用嘛。</li> <li>怎么样偷呢？这两个move 版本都是在偷东西，怎么去偷呢？</li></ul></li></ul> <h3 id="_25-1-编码的坑⭐️"><a href="#_25-1-编码的坑⭐️" class="header-anchor">#</a> 25.1.编码的坑⭐️</h3> <ul><li><p>自己看PPT上，<code>str._data=NULL</code>重要！！</p></li> <li><p>一般人这行可能会忽略掉，可能会想：嗯，弄为零的话，那要不要把他自己清掉算了，免得后面被误用。不应该在这里做，是应该要清除它，但是这个清除动作，应该交给destruct 析构函数去做，所以不应该在这里做。</p></li> <li><p>所以一般很多的朋友呢可能就会忽略说啊，那这样的话呢这个指针也是过来了，长度也设为零了。可以了。这就结束了。
<strong>可是这样会引发一个大问题，如果你没有写这一行的。会怎么样呢</strong>？</p> <ul><li>刚刚说很重要的<strong>就是这个要设为null，把它打断的意思『记住哈，len=0不是打断！』</strong>。很多人忽略没打断没打断的话呢。</li> <li>这样的话，执行完毕之后，这个临时对象。临时对象的生命结束，他的生命力消失，析构函数就会被吊起来！！！然后就会把这根这个地方杀掉，这个一点例子就把这一块也等于是一起杀掉了。这两个人在看同一款。！！</li></ul></li> <li><p>这就是我们。第一次终于面对我们要怎么写一个copy 版本的兄弟版本move，啊，要这么写。</p></li></ul> <h3 id="_25-2-move的和析构函数判别null"><a href="#_25-2-move的和析构函数判别null" class="header-anchor">#</a> 25.2.move的和析构函数判别NULL</h3> <p>然后偷完之后呢，那来源端着把它把自己的状态设一下，长度设为零。指针设为null。我这边又一次告诉你这一行重要。
设为呢这个打包。所以这里就可以看出他的配套了，这里设为null 之后呢，析构函数这边就会去检查。
不是NULL的情况下才给力。这就是他的完整故事。</p> <p>一个对move 有意识的一种class。好吧。</p> <p>好，这一个元素类型，由于我等一下做测试的时候。我要以不同的容器来都放这种元素来来测一下这个这个。
测了一下这个效率。当我把它放到关联式的容器的时候。
关联式容器是什么？就像set、map
不过这个hash 这个东西到了二点零有新的名称，这等一下再说。<strong>像这一种容器的，它都要检测元素的大小</strong>。</p> <h3 id="_25-3-为什么重载-和-呢？⭐️"><a href="#_25-3-为什么重载-和-呢？⭐️" class="header-anchor">#</a> 25.3.为什么重载<code>&lt;</code>和<code>=</code>呢？⭐️</h3> <p>为了应付这个事情，为了应付这个融这个元素放到那种特殊容器身上，所以我在继续发展。他写一个这个<code>&lt;</code>的动作。还写一个等于的动作。</p> <ul><li>这两件事情跟这个<code>move awarew</code> 是没有关系的。只是为了测试，我这边有写，为了set。</li></ul> <p>我去讲他那这个地方，我是借用，由于我这里头，是一个c 风格的字符串，我这个my string 是个C风格，this style 字符串。我就借用把它当做把它转换为c 加加的string。那cj 叫st string 本身就已经可以比大小了。<strong>我借用这个让我的写代码更更简单一点。</strong> <strong>在现实中，你当然不会这么做。</strong></p> <ul><li><strong>前面有一些counter，它是静态的数据，所以我必须在class 的外头，把它定义出来，并且全部我现在把它全部设为零。</strong></li></ul> <h3 id="_25-4-后续测试的准备"><a href="#_25-4-后续测试的准备" class="header-anchor">#</a> 25.4.后续测试的准备</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711090903090.png" alt="image-20210711090903090"></p> <ul><li>由于我等一下测试的时候，我不但把它放在我把它放在各种容器！！其中我会把它set，set 的背后是一个hashtable，而hashtable 需要hashcode和hashfunction方式，这个概念等一下会提，所以我必须写出一个hashfunction出来，就是蓝色的这一块。<strong>啊，这个跟现在这个主题无关，所以我们都先跳过。我只解释说我必须写出这些东西。</strong></li></ul> <h2 id="_26-move-aware-class-对容器的『效能测试』"><a href="#_26-move-aware-class-对容器的『效能测试』" class="header-anchor">#</a> 26.Move-aware class 对容器的『效能测试』</h2> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711091545919.png" alt="image-20210711091545919"></p> <p>嗯，写完之后开始测试！它那个测试函数又再一次跑出来了，出现好多次，在这1讲里面已经出现好几次了。
在前面第一讲的讲语语法的时候，也因为某些因素啊，谈到一些相关主题也出现过就是这个<code>test_moveable</code>。</p> <p>不过我想跟你说明，它在出现的时候，接口，有时候不太一样，像这个接口是是接受这样的东西，可是刚刚出现的时候，回到我们前面他只接受一个，实际上我给你的代码呢是。是现在来再一次是现在这样的版本，只是有时候我会感觉，诶我还可以把它跟再做一些变化，就变成刚刚那个版本，否则不同而已。
有的是接受一个，有的是接受两个，这其实无所谓。无所谓啊，当我这个接受两个的时候，我是在同一个函数里头去做两次的测试。如果我接受了一个，我就是只做一次的测试。这个得等到你说拿到这个完整的代码，看一下，你就会明白我现在在说什么。清楚的明白。
所以有时候前后呢这个地方接口有一点不一致啊，大家注意，其实无伤大雅。
现在我要测试了，我就放调用这个函数呢。</p> <p>好，这<strong>样300万次在vector身上执行</strong>，结果在这里。</p> <p>后面的投影片就是我现在很快的，快放一遍。针对vector，这个是针对list，这个是针对dequeup，这个是针对ms。MC的背后是红黑树，这个是针对啊older的MD。CD，这个背后是table，PC表。啊这样我就把最核心的容器都测试一次，看看他们的效果怎么样。</p> <h3 id="_26-1-vector的测试"><a href="#_26-1-vector的测试" class="header-anchor">#</a> 26.1.vector的测试</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711092614712.png" alt="image-20210711092614712"></p> <ul><li>发现，PPT上几乎两倍两倍差别很大，在我的测试里面还有更巨大的，有差10倍的。因为这过程中要跟要取决于你的当时的环境变了，计算机里面的内存的分布啦，有没有碎片啦等等啊</li> <li>这样已经算是差距很小了，但是现在这个例子，但仍然有差到两倍，不可谓不大。这里面出现调用的次数，我们放的是带有move意识的那一种，所以调用的都是MCtor，七百万次。</li> <li>这两个上下两个时间差别其实就是因为上面调用了这个版本，而下面调用这个版本。</li> <li>上面这是偷的，下面这个是真的有分配类。当然效率差很多！！</li></ul> <p>另外<strong>有一个值得注意的是</strong>，这里明明你放300万个元素，为什么他调用了700万次的构造函数呢？
按理说不应该也是三百万次吗？你准备了三百万个临时对象，我是一些随机数做成的字符串，把三百万个放音色放进去就应该做三百万次的。
happy或者是木看可不可以被偷。
那怎么会是七百万？这是因为vector也会成长，当他不够的时候，他会两倍成长，而成长的过程是很痛苦的啊，成长的过程它就会把原来的东西搬到我不能吃，现在不能再乱用班这个字眼了，会跟我们这个现在谈的这个主题冲突啊他<strong>会被拷贝到另外一个新地方去。</strong>
这些都是暗中发生的，你不知道的，原来有七百万次比三百万次你预想的多太多。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711091545919.png" alt="image-20210711091545919"></p> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>M <span class="token function">c11</span><span class="token punctuation">(</span>c1<span class="token punctuation">)</span><span class="token punctuation">;</span>
M <span class="token function">c12</span><span class="token punctuation">(</span>std<span class="token operator">::</span><span class="token function">move</span><span class="token punctuation">(</span>c1<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	c11<span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span>c12<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><p>那这个对于vector的测试呢完成了，前面的PPT后面还有两个还有3个测试一直没有谈呢。
我们再回到前面这个测试程序这里把三百万个元素放进去之后，我现在这三个动作是什么？
<strong>对于容器做copy，现在不是元素了，是容器本身做copy</strong>，下面这个呢也是做copy。
<strong>不过我特别叫他故意的说我是一个右值</strong>，我整个容器是一个右值，我看看你会效率上会怎么样？？
第三个动作做swap，交换，交换想好像想象中也会有很多的copy
我们做这三个动作，看看他花的时间。
后面的每一个容器我也都做这三个动作。</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711092614712.png" alt="image-20210711092614712">
好，花的时间呢在这边的PPT，下面的！！！copy就是这三行，这三行再抄过来比较容易比对这三行。</p> <ul><li><p>第一次是做copy，花掉的时间这么多</p></li> <li><p>第二次是move的copy，幕府版本花掉了0个minister，当然不可能时间是0啊，只是我在观察的时候，我的刻度是到毫秒。minister，他可能是到了跟零点零几的毫秒。出来是零，这个差距就非常非常大了，简直是无穷大的差差距。</p></li> <li><p>第三个呢，swap两个容器。这个容器里头有三百万个元素啊，两个容器要交换，他花的时间也是零。</p></li> <li><p><strong>我们等一下再来探讨这三笔数据为什么差别这么大</strong>？是对容器本身只整个整体来做动作啊，上面呢是对一个一个的元素做动作。</p></li></ul> <h3 id="_26-2-测试list"><a href="#_26-2-测试list" class="header-anchor">#</a> 26.2.测试list</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711093510378.png" alt="image-20210711093510378"></p> <ul><li>差别非常小，可见这个copy啊的次数。差别非常小，可见这个copy啊的次数。</li></ul> <h3 id="_26-3-测试deque"><a href="#_26-3-测试deque" class="header-anchor">#</a> 26.3.测试deque</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711093632635.png" alt="image-20210711093632635"></p> <p>deque 这个的长相是这个样子，它是一个分段连续的分段连续。
由于我的元素总是放在最尾巴，在我的测试程序里头，我总是放在最尾巴，所以其实他不会有他不会。
呃大量的copy的动作，如果我作为一个在这里放了一个元素这里，那么这个会找比较近的，就往头走或往尾巴走，谁比较近呢？
<strong>他会找到那个比较短的、比较近的那一边呢去做推的动作</strong>，这样才能够insert而进来。
所以在推的过程里面就会有很多的cp，但<strong>我现在是三百万次的放在尾巴，所以不会有这种推的动作</strong>。
<strong>所以嗯在这里呀三百万次的摘掉这个版本，或者是调这个版本，幕府版本，或者是copy版本，影响不大</strong>。
好，其他的这个变化呢都跟上一页这个list差不多，分析都是差不多的。</p> <h3 id="_26-4-测试multiset"><a href="#_26-4-测试multiset" class="header-anchor">#</a> 26.4.测试multiset</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711094020738.png" alt="image-20210711094020738"></p> <p>再往下，它的背<strong>后是红黑树，其实都是一个个的节点，就在概念上你可以想它跟list差不多</strong>，就目前我要讨论的事情，他跟例子电表差不太多，都是节点。所以三百万次的安插呢这个影响不大。</p> <h3 id="_26-5-测试unordered-multiset"><a href="#_26-5-测试unordered-multiset" class="header-anchor">#</a> 26.5.测试unordered_multiset</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711094248889.png" alt="image-20210711094248889"></p> <p>再往下，**这一个是二点零的新容器，其实背后是hashtable，在1.0也已经存在hashtable。这个这件事情我们等下再说啊。**这是他的测试。结果。</p> <h3 id="_26-6-测试结果⭐️"><a href="#_26-6-测试结果⭐️" class="header-anchor">#</a> 26.6.测试结果⭐️</h3> <p><strong>所以我们从这些测试里面得到一个概念：就是看起来似乎只有对于vector影响非常大，你的元素他带不带着move的意识？带或不带对于vector这个容器影响最大，对于其他容器似乎没有什么影响</strong>。</p> <p><font style="background:yellow;">啊确实是这样，但对于deque，这个我们的测试没有测试某种情况，在那种情况之下呢也是有巨大影响的。</font>
什么情况？就是我刚刚讲insert在中间某个地方，那他就要推要挤，这过程里面会有很多的copy，如果你做这种动作，这个影响就会呈现出来。我没有做这个动作。</p> <p>所以这一些你再把这五页这个容器的结构啊看一看，你会发现只要这个容器是以节点的形式存在，这个有没有就是move constructor或copy constructor，到底是调用哪一个呢？其实影响不大，影响不大。</p> <h3 id="_26-7-讨论⭐️"><a href="#_26-7-讨论⭐️" class="header-anchor">#</a> 26.7.讨论⭐️</h3> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711094912997.png" alt="image-20210711094912997"></p> <p>好，最后我们来讨论。刚刚我再往前看啊，这有五张这种黑画面。
呃测试结果我的第一张有写。这三行后面五章都有，可是我就没有再打出来了。
这三行为什么这个copy？
我等一下要谈的是对vector的这个容器，为什么这个时间这么长？3500，下面这个时间是零。</p> <p>第三个动作也是你我要讨论这一件事情。
这个讨论是对整个容器的做动作，不再是一个一个的元素做动作。
我们看看这个可能有三个动作，就是前两个，第三个是swap这一个动作。
我现在你手上会拿到两页，这一页是第一个动作，下一页是第二个动作，我们可以好好的来。
叫好，我们先看上面这一个，这是cup，这是copy，我们要去看源代码就能够很好地解释。
好，跑到这里来，这个是外特的copy，在这个copy里头所做的事情，最重要的动作我都已经把你圈起来了，这个圈起来它代表什么行为？
线条全部拉好了，这里所做的动作这边的变量，你可以参考这一张，你就可以看得出来，<strong>它其实是把如果来源端是这样的话，它是把来源端的头尾一个一个的拷贝到。</strong> <strong>目的端去</strong>，当然目的端要先分配出适当的、足够的空间出来，然后调用像这个图是五次的。
copy。
ctrl，你有三百万个元素，那就是三百万次。
copy，ctrl，<strong>那是真正的copy，当然慢！！</strong>！</p> <p><img src="https://cdn.jsdelivr.net/gh/HACV/picture/img/image-20210711095123917.png" alt="image-20210711095123917"></p> <p>第二个动作呢也是copy，但是我告诉他说，你把我当右值吧。于是他他只说到是幼稚，他就知道他可以通，他怎么偷呢？
所以这一个动作所调用的现在线条拉到这里，这是一个move版本。
再看一次，上上一页调用到的是这是copy版本，现在要用到的是move版本这里。
那这里所做的事情，好，继续拉，拉到这里，这里面下面要做的事情再拉。
你就循着这个线条，这我们就不把时间停在这里了啊。
啊你恐怕这一页投影片你都要花上个十五分钟，十分钟能慢慢的去体会。
线索都帮你拉好了，最后跑到这个地方来，这个名字叫做swap_datad，他所做的事情其实只是把指针交换而已。</p> <p>所以<strong>交换完之后，目的端跟来源端你可以想象啊，是这也是事实，它其实指向同一块东西</strong>。</p> <p>我这张图呢因为表现的是一个V，是有三根指针，所行之所这说建立起来头尾看这个空间的最尾巴，三根指针呃经过这个词第一这个动作跑到这里来，其实只是这三根指针两组每一组这三根指针的交换。那等于等于把这个变量抄过来，等于这两根指针都指向这里这两根都指向这里。</p> <p>这两个都是相生，和他们共享了，他们被偷了，为什么呢？
因为你告诉他，你的这个容器是又直，所以他放心的。
他他是谁？<strong>他就是这样这样这样这样跑到这里来之后，他放心的去做偷的动作。那只三根指针的交换和三个指针的复制好了，那速度是快的不得了</strong>。</p> <p>好，所以这是一个很大的话题。</p> <ul><li>第一，我们学会了怎么对一个准备要来做容器的元素的这种类型，怎么对一个这种类型去设计，然后带着move意式，并且我们也看到了它对容器，所以这种东西真的要将来要放到这种这种新设计的这种类型，确实真的要放到容器里头去呀。</li> <li>它对容器的效率的影响</li> <li>就是这个单元，很复杂的一个单元。</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>⏳27. 容器—结构与分类_旧与新的比较 — 关于实现手法
⏳28. 容器 array
⏳29. 容器 Hashtable
- 哈希表
⏳30无Unordered
- unordered
⏳31无Hash function
- 哈希函数
⏳32无forward_list『单链表』
- 单链表
⏳33无一个万用的Hash Function
⏳34. Tuple
- STL新特性，
⏳无5.35.shared_pointer
- 共享指针
⏳无5.36.Type traits
- 类型萃取

20、容器类
(1) 序列式容器包括：array(C++2.0 新引入),vector,deque,list,forward_list(C++2.0 新引入)
(2) 关联式容器包括：set/multiset,map/multimap
(3) 无序容器(C++2.0 新引入,更换原先 hash_xxx 为 unordered_xxx)包括：unordered_map/unordered_multimap,unordered_set/unordered_multiset
(4)Hash Function
(5)tuple
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><h4 id="萃取-traits-技巧"><a href="#萃取-traits-技巧" class="header-anchor">#</a> 萃取 traits 技巧</h4> <h4 id="菱形继承"><a href="#菱形继承" class="header-anchor">#</a> 菱形继承</h4> <ul><li>CSDN<a href="https://blog.csdn.net/jackystudio/article/details/17877219" target="_blank" rel="noopener noreferrer">解释得不错<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <h4 id="volatile"><a href="#volatile" class="header-anchor">#</a> volatile</h4> <h2 id="参考资料"><a href="#参考资料" class="header-anchor">#</a> 参考资料</h2> <ul><li>C++<a href="https://mooc.study.163.com/smartSpec/detail/1001137001.htm" target="_blank" rel="noopener noreferrer">网易云微专业<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>，侯捷</li></ul></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/30.805597a8.js" defer></script>
  </body>
</html>
